home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / 3dvect39 / math.inc < prev    next >
Text File  |  1994-10-30  |  81KB  |  3,091 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ;        Filename     : Math.inc
  4. ;        Included from: 3D1.ASM, 3D2.ASM, 3D3.ASM
  5. ;        Description  : General math functions.
  6. ;
  7. ;        Written by: John McCarthy
  8. ;                    1316 Redwood Lane
  9. ;                    Pickering, Ontario.
  10. ;                    Canada, Earth, Milky Way (for those out-of-towners)
  11. ;                    L1X 1C5
  12. ;
  13. ;        Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;                Fidonet:  Brian McCarthy 1:229/15
  15. ;          RIME/Relaynet: ->CRS
  16. ;
  17. ;        Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; Send me your protected mode source code!
  20. ; Send me your Objects!
  21. ; But most of all, Send me a postcard!!!!
  22. ;
  23. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  24.  
  25.          public _rotate_point               ; _rotate_point using _vmatrix
  26.          public _user3d                     ; calculate 3d ?actual*?/z (both x and y)
  27.          public _user3dx                    ; xactual*x/z
  28.          public _user3dy                    ; yactual*y/z
  29.          public _rotate_by_camera           ; 32 bit _rotate_point using _ematrix
  30.          public _zsolve                     ; solve single equation variable
  31.          public _ysolve
  32.          public _xsolve
  33.          public _cosine
  34.          public _sine
  35.          public _arctan
  36.          public _compound                   ; generate rotation matrix (includes camera)
  37.          public _setsincose                 ; set camera matrix
  38.          public _temp_matrix                ; set user defined/temporary matrix
  39.          public _temp_rotate_point          ; rotate point by temp matrix (tmatrix)
  40.          public _matrix_multiply            ; multiply _tmatrix by _vmatrix
  41.          public _null_y_matrix
  42.          public _inverse_rotate
  43.          public _rotate_x
  44.          public _rotate_y
  45.          public _rotate_z
  46.          public _point_z                    ; align z angle to point EBX,ECX and EBP
  47.          public _sqrt                       ; eax=sqr(eax), thanks to TRAN!
  48.  
  49.          public _pre_cal_lambert            ; scan object si and calculate surface normals
  50.          public _calc_normal                ; guess...from 3 points, returns vector ebx,ecx,ebp
  51.          public _calc_d                     ; calculate D from plane equation
  52.          public _lambert                    ; calculate surface normal rotation matrix for object si
  53.          public _set_up_all_lambert         ; scans objects from si to di and calls _pre_cal_lambert
  54.          public _l_rotate_point             ; given normal for surface, figures out intensity
  55.  
  56.          public _lx1                        ; points to load up before calling _calc_normal
  57.          public _ly1
  58.          public _lz1
  59.          public _lx2
  60.          public _ly2
  61.          public _lz2
  62.          public _lx3
  63.          public _ly3
  64.          public _lz3
  65.  
  66.          align 4
  67.  
  68. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  69. ;
  70. ; _rotate_point - 32 bit _rotate_point point using _vmatrix
  71. ; In:
  72. ;    EBX - x point
  73. ;    ECX - y point
  74. ;    EBP - z point
  75. ;     _vmatrix - 32 bit rotation matrix - set up by "_compound" routine
  76. ; Out:
  77. ;    EBX - x point
  78. ;    ECX - y point
  79. ;    EBP - z point
  80. ;
  81. ; Notes:
  82. ;
  83. ; All rotations (_rotate_by_camera,_rotate_point,_temp_rotate_point) are 32 bit.
  84. ; _f_rotate_point uses rotation along a plane and uses _ematrix with _precal147
  85. ;
  86. ; point rotation
  87. ; ebx = x   ecx = y   ebp = z    32 bit rotation!
  88. ; clobbers edx,esi,eax
  89. ;
  90. ; remember , matrix offsets are:
  91. ;
  92. ;  0 1 2     multiply those by 4 for the word address of the matrix
  93. ;  3 4 5
  94. ;  6 7 8
  95. ;
  96. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  97.  
  98. _rotate_point:
  99.          mov eax,_vmatrix+8                 ; solve x = bx(0)+cx(1)+bp(2)
  100.          imul ebp
  101.          shrd eax,edx,14
  102.          mov edi,eax
  103.          mov eax,_vmatrix+4
  104.          imul ecx
  105.          shrd eax,edx,14
  106.          add edi,eax
  107.          mov eax,_vmatrix+0
  108.          imul ebx
  109.          shrd eax,edx,14
  110.          add edi,eax                        ; di = new x
  111.  
  112.          mov eax,_vmatrix+20                ; solve y = bx(3)+cx(4)+bp(5)
  113.          imul ebp
  114.          shrd eax,edx,14
  115.          mov esi,eax
  116.          mov eax,_vmatrix+16
  117.          imul ecx
  118.          shrd eax,edx,14
  119.          add esi,eax
  120.          mov eax,_vmatrix+12
  121.          imul ebx
  122.          shrd eax,edx,14
  123.          add esi,eax                        ; si = new y
  124.  
  125.          mov eax,_vmatrix+32                ; solve z = bx(6)+cx(7)+bp(8)
  126.          imul ebp
  127.          shrd eax,edx,14
  128.          mov ebp,eax
  129.          mov eax,_vmatrix+28
  130.          imul ecx
  131.          shrd eax,edx,14
  132.          add ebp,eax
  133.          mov eax,_vmatrix+24
  134.          imul ebx
  135.          shrd eax,edx,14
  136.          add ebp,eax                        ; bp = new z
  137.  
  138.          mov ecx,esi
  139.          mov ebx,edi
  140.  
  141.          ret
  142.  
  143. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  144. ;
  145. ; _user3d - scale 3d point into 2d point
  146. ; In:
  147. ;    EBX - x point
  148. ;    ECX - y point
  149. ;    EBP - z point
  150. ; Out:
  151. ;    EBX - x point
  152. ;    ECX - y point
  153. ;    EBP - z point
  154. ;
  155. ; Notes:
  156. ;
  157. ; fast ratios found in macros.inc since
  158. ; multiplication has been substituted with fast lea
  159. ;
  160. ; trashes eax,edx,edi
  161. ;
  162. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  163.  
  164. _user3d:                                    ; bp must always be non-zero
  165.          cmul eax,ebx,ratiox                ; use fast constant multiply
  166.  
  167.          idiv ebp
  168.          mov ebx,eax
  169.  
  170. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  171. ;
  172. ; _user3dy - scale 3d point into 2d point on x axis only
  173. ; In:
  174. ;    ECX - y point
  175. ;    EBP - z point
  176. ; Out:
  177. ;    ECX - y point
  178. ;    EBP - z point
  179. ;
  180. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  181. _user3dy:
  182.          cmul eax,ecx,ratioy
  183.  
  184.          idiv ebp
  185.          mov ecx,eax
  186.  
  187.          ret
  188.  
  189. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  190. ;
  191. ; _user3dx - scale 3d point into 2d point on y axis only
  192. ; In:
  193. ;    EDI - x point
  194. ;    ESI - z point
  195. ; Out:
  196. ;    EDI - x point
  197. ;    ESI - z point
  198. ;
  199. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  200.  
  201. _user3dx:                                   ; bp must always be non-zero
  202.          cmul eax,edi,ratiox
  203.  
  204.          idiv esi
  205.          mov edi,eax
  206.  
  207.          ret
  208.  
  209. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  210. ;
  211. ; Checkfront: checks if a side is visible. (counter-clockwise)
  212. ;
  213. ; In:
  214. ;   (EDI,EBP) - xy of point 1
  215. ;   (ESI,ECX) - xy of point 2
  216. ;   (EDX,EBX) - xy of point 3
  217. ; Out:
  218. ;   ECX < 0 if side counter-clockwise
  219. ;
  220. ; Notes: routine courtesy of "RAZOR"
  221. ; eg:
  222. ;          call checkfront
  223. ;          cmp ecx,0
  224. ;          jng dontdraw
  225. ;
  226. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  227.  
  228.  
  229.          align 4
  230.  
  231. checkfront:
  232.          cmp edi,esi
  233.          jng s cfc
  234.          mov eax,edi
  235.          mov edi,esi
  236.          mov esi,edx
  237.          mov edx,eax
  238.          mov eax,ebp
  239.          mov ebp,ecx
  240.          mov ecx,ebx
  241.          mov ebx,eax
  242. cfc:
  243.          mov eax,edx                        ; ax = x3
  244.          sub eax,edi                        ; ax = x3 - _x1
  245.          sub ecx,ebp                        ; cx = _y2 - _y1
  246.          imul ecx                           ; ax = (x3-_x1)*(_y2-_y1)
  247.          mov ecx,eax                        ; save it...
  248.          mov eax,esi                        ; ax = _x2
  249.          sub eax,edi                        ; ax = _x2 - _x1
  250.          sub ebx,ebp                        ; bx = y3 - _y1
  251.          imul ebx                           ; ax = (_x2-_x1)*(y3-_y1)
  252.          sub ecx,eax                        ; cx = (x3-_x1)*(_y2-_y1)-(_x2-_x1)*(y3-_y1)
  253.          ret
  254.  
  255. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  256. ;
  257. ; _rotate_by_camera - 32 bit _rotate_point point using _ematrix
  258. ; In:
  259. ;    EBX - x point
  260. ;    ECX - y point
  261. ;    EBP - z point
  262. ;     _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  263. ; Out:
  264. ;    EBX - x point
  265. ;    ECX - y point
  266. ;    EBP - z point
  267. ;
  268. ; Notes:
  269. ;
  270. ; point rotation for eye - solves all x,y,z parameters
  271. ; camera rotation is 32 bit and uses _ematrix
  272. ;
  273. ; remember , matrix offsets are:
  274. ;
  275. ;  0 1 2     multiply those by 4 for the doubleword address of the matrix
  276. ;  3 4 5
  277. ;  6 7 8
  278. ;
  279. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  280.  
  281.          align 4
  282.  
  283. _rotate_by_camera:
  284.          mov eax,_ematrix+8
  285.          imul ebp
  286.          shrd eax,edx,14
  287.          mov edi,eax
  288.          if usez eq yes
  289.          mov eax,_ematrix+4
  290.          imul ecx
  291.          shrd eax,edx,14
  292.          add edi,eax
  293.          endif
  294.          mov eax,_ematrix+0
  295.          imul ebx
  296.          shrd eax,edx,14
  297.          add edi,eax                        ; di = new x
  298.  
  299.          mov eax,_ematrix+20
  300.          imul ebp
  301.          shrd eax,edx,14
  302.          mov esi,eax
  303.          mov eax,_ematrix+16
  304.          imul ecx
  305.          shrd eax,edx,14
  306.          add esi,eax
  307.          mov eax,_ematrix+12
  308.          imul ebx
  309.          shrd eax,edx,14
  310.          add esi,eax                        ; si = new y
  311.  
  312.          mov eax,_ematrix+32
  313.          imul ebp
  314.          shrd eax,edx,14
  315.          mov ebp,eax
  316.          mov eax,_ematrix+28
  317.          imul ecx
  318.          shrd eax,edx,14
  319.          add ebp,eax
  320.          mov eax,_ematrix+24
  321.          imul ebx
  322.          shrd eax,edx,14
  323.          add ebp,eax                        ; bp = new z
  324.  
  325.          mov ecx,esi
  326.          mov ebx,edi
  327.  
  328.          ret
  329.  
  330. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  331. ;
  332. ; _zsolve - 32 bit rotate point using _ematrix - solve one variable only
  333. ; In:
  334. ;    EBX - x point
  335. ;    ECX - y point
  336. ;    EBP - z point
  337. ;    _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  338. ;
  339. ; Out:
  340. ;    EBX - x point (same as entry)
  341. ;    ECX - y point (same as entry)
  342. ;    EBP - z point (same as entry)
  343. ;    ESI - new z point/location
  344. ;
  345. ; Notes:
  346. ;
  347. ; solve z from _ematrix - same as above _rotate_by_camera but only solves z for fast
  348. ; test of where object is - result is in esi
  349. ;
  350. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  351.  
  352.          align 4
  353.  
  354. _zsolve:
  355.          mov eax,_ematrix+32
  356.          imul ebp
  357.          shrd eax,edx,14
  358.          mov esi,eax
  359.          mov eax,_ematrix+28
  360.          imul ecx
  361.          shrd eax,edx,14
  362.          add esi,eax
  363.          mov eax,_ematrix+24
  364.          imul ebx
  365.          shrd eax,edx,14
  366.          add esi,eax                        ; si = new z
  367.          ret
  368.  
  369. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  370. ;
  371. ; _xsolve - 32 bit rotate point using _ematrix - solve one variable only
  372. ; In:
  373. ;    EBX - x point
  374. ;    ECX - y point
  375. ;    EBP - z point
  376. ;    _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  377. ;
  378. ; Out:
  379. ;    EBX - x point (same as entry)
  380. ;    ECX - y point (same as entry)
  381. ;    EBP - z point (same as entry)
  382. ;    EDI - new x point/location
  383. ;
  384. ; Notes:
  385. ; If object z test from above routine is positive, this routine will solve
  386. ; the rest of the rotation matrix.  this is so we don't waste time solving
  387. ; for x and y locations if the object is behind the camera anyway.
  388. ; Saves imuls.
  389. ;
  390. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  391.  
  392.          align 4
  393. _xsolve:
  394.          mov eax,_ematrix+8
  395.          imul ebp
  396.          shrd eax,edx,14
  397.          mov edi,eax
  398.          if usez eq yes
  399.          mov eax,_ematrix+4
  400.          imul ecx
  401.          shrd eax,edx,14
  402.          add edi,eax
  403.          endif
  404.          mov eax,_ematrix+0
  405.          imul ebx
  406.          shrd eax,edx,14
  407.          add edi,eax                        ; di = new x
  408.          ret
  409.  
  410. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  411. ;
  412. ; _ysolve - 32 bit rotate point using _ematrix - solve one variable only
  413. ; In:
  414. ;    EBX - x point
  415. ;    ECX - y point
  416. ;    EBP - z point
  417. ;    ESI - new z point
  418. ;    EDI - new x point
  419. ;    _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  420. ;
  421. ; Out:
  422. ;    EBX - x new point from EDI
  423. ;    ECX - y new point
  424. ;    EBP - z new point from ESI
  425. ;
  426. ; Notes:
  427. ;
  428. ; Solve y from _ematrix - same as above _xsolve but solves y for fast
  429. ; test of where object is.  Final variables are then cleaned up to
  430. ; immitate the _rotate_by_camera function in parts.
  431. ;
  432. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  433.  
  434.          align 4
  435. _ysolve:
  436.          mov eax,_ematrix+16
  437.          imul ecx
  438.          shrd eax,edx,14
  439.          mov ecx,eax
  440.          mov eax,_ematrix+12
  441.          imul ebx
  442.          shrd eax,edx,14
  443.          add ecx,eax
  444.          mov eax,_ematrix+20
  445.          imul ebp
  446.          shrd eax,edx,14
  447.          add ecx,eax                        ; cx = new y
  448.  
  449.          mov ebx,edi                        ; final test, move into appropriate regs
  450.          mov ebp,esi
  451.  
  452.          ret
  453.  
  454. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  455. ;
  456. ;   _sine - 16 bit theta to 32bit sin(@)
  457. ; In:
  458. ;     AX - theta  0 - 65536 (0-360)
  459. ; Out:
  460. ;    EAX - sin (@)   (-4000h to 4000h)
  461. ;
  462. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  463. ;
  464. ; _cosine - 16 bit theta to 32bit cos(@)
  465. ; In:
  466. ;     AX - theta  0 - 65536 (0-360)
  467. ; Out:
  468. ;    EAX - cos (@)   (-4000h to 4000h)
  469. ;
  470. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  471. ;
  472. ; Notes:
  473. ; calculate sin into eax, from ax, smashes bx
  474. ; after imul by sin, shr eax,14 to compensate for decimal factor!
  475. ;  eg:
  476. ;    mov eax,sin(@)
  477. ;    mov ebx,32bitnumber
  478. ;    imul ebx
  479. ;    shrd eax,edx,14
  480. ;    eax = ebx*sin(@)
  481. ;
  482. ;    mov ax,sin(@)
  483. ;    mov bx,16bitnumber
  484. ;    imul bx
  485. ;    shrd ax,dx,14
  486. ;    eax = bx*sin(@)
  487. ;
  488. ; eax is only a sign extended ax and will contain either ffffxxxx or 0000xxxx
  489. ;
  490. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  491.  
  492.          align 4
  493.  
  494. _cosine:
  495.          add ax,4000h
  496. _sine:
  497.          shr ax,2
  498.          cmp ax,2000h
  499.          jge s q3o4                         ; quadrant 3 or 4
  500.  
  501.          cmp ax,1000h
  502.          jl s q0                            ; quad 1
  503.  
  504.          mov ebx,1fffh
  505.          sub bx,ax
  506.          jmp s half_sine                    ; quad 2
  507. q0:
  508.          movzx ebx,ax
  509.          jmp s half_sine
  510. q3o4:
  511.          cmp ax,3000h
  512.          jl s q3
  513.          mov ebx,3fffh
  514.          sub bx,ax
  515.          call half_sine                     ; quad 4
  516.          neg eax
  517.          ret
  518. q3:
  519.          and ax,0fffh
  520.          movzx ebx,ax                       ; quad 3
  521.          call half_sine
  522.          neg eax
  523.          ret
  524. half_sine:
  525.          xor eax,eax
  526.          mov ax,w sinus[ebx*2]
  527.          ret
  528.  
  529. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  530. ;
  531. ; Arctan - 32 bit rise/run to 16bit arctan(rise/run)
  532. ; In:
  533. ;    EAX - Run
  534. ;    ECX - Rise
  535. ; Out:
  536. ;     AX - arctan(ECX/EAX)
  537. ;
  538. ; Notes:
  539. ; smashes cx,ax,dx,si
  540. ; arctan(ecx/0) is valid and tested for
  541. ;
  542. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  543.  
  544.          align 4
  545.  
  546. _arctan:
  547.          or eax,eax
  548.          jl s qd2or3
  549.          je findmax
  550.          or ecx,ecx
  551.          jge s halftax                      ; quadrant 1
  552.          neg ecx                            ; quadrant 4, ax=-ax
  553.          call halftan
  554.          neg ax
  555.          shl eax,2
  556.          ret
  557. qd2or3:
  558.          neg eax
  559.          or ecx,ecx
  560.          jge s qd2
  561.          neg ecx                            ; quad 3, ax=ax+8192
  562.          call halftan
  563.          add ax,8192
  564.          shl eax,2
  565.          ret
  566. qd2:
  567.          call halftan
  568.          neg ax
  569.          add ax,8192
  570.          shl eax,2
  571.          ret
  572. halftax:
  573.          call halftan
  574.          shl eax,2
  575.          ret
  576.  
  577.          align 4
  578.  
  579. halftan:
  580.          xor edx,edx
  581.  
  582. ; cx=rise  positive
  583. ; ax=run   positive
  584.  
  585.          cmp eax,ecx
  586.          jl s opptan                        ; greater than 45 degrees, other side...
  587.  
  588.          xchg ecx,eax                       ; ax<cx
  589.          shld edx,eax,11                    ; *2048 edx = high dword for divide
  590.          shl eax,11                         ; *2048
  591.          div ecx
  592.          movzx esi,ax
  593.          mov ax,w negtan[esi*2]             ; resulting angle (0-512 is 0-45) in ax
  594.          ret
  595.  
  596.          align 4
  597.  
  598. opptan:
  599.          shld edx,eax,11                    ; *2048 edx = high dword for divide
  600.          shl eax,11                         ; *2048
  601.  
  602.          div ecx
  603.          movzx esi,ax                       ; ax remainder
  604.          mov cx,w negtan[esi*2]
  605.          mov eax,1000h
  606.          sub ax,cx                          ; resulting angle (2048-4096 is 45-90) in ax
  607.          ret
  608.  
  609. findmax:
  610.          mov eax,16384
  611.          or ecx,ecx
  612.          jge _ret
  613.          neg eax
  614.          ret
  615.  
  616.          align 4
  617.  
  618. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  619. ;
  620. ; _compound - generate object matrix, 12 imul's first
  621. ; In:
  622. ;    ESI - Object # to get angles from
  623. ;    v_vxs[esi*2] - object x angle (0-65536)
  624. ;    v_vys[esi*2] - object y angle (0-65536)
  625. ;    v_vzs[esi*2] - object z angle (0-65536)
  626. ; Out:
  627. ;    _vmatrix - resulting rotation matrix including camera matrix
  628. ;    ESI = ESI
  629. ;
  630. ; Notes:
  631. ;              x                         y                      z
  632. ;
  633. ;x=  cz * cy - sx * sy * sz   - sz * cy - sx * sy * cz     - cx * sy
  634. ;
  635. ;y=         sz * cx                   cx * cz                - sx
  636. ;
  637. ;z=  cz * sy + sx * sz * cy   - sy * sz + sx * cy * cz       cx * cy
  638. ;
  639. ;then perform matrix multiply by negative x and z matricies
  640. ;
  641. ; -x matrix                             -z matrix
  642. ;     x       y       z                   x       y       z
  643. ;
  644. ;x    1       0       0                cz     sz       0
  645. ;
  646. ;y    0      cx       sx              -sz     cz       0
  647. ;
  648. ;z    0     -sx       cx                0      0       1
  649. ;
  650. ; Notice original object matrix takes 12 imuls, camera modify takes 24, can
  651. ; you do this faster? (less imuls)
  652. ;
  653. ; A call to _setsincose MUST have taken place for this routine to calculate
  654. ; the camera matrix correctly.
  655. ;
  656. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  657.  
  658. _compound:
  659.          push esi
  660.  
  661.          mov ax,v_vxs[esi*2]
  662.          neg ax
  663.          push eax
  664.          call _cosine
  665.          mov vcosx,eax
  666.          pop eax
  667.          call _sine
  668.          mov vsinx,eax
  669.          mov ebp,eax                        ; bp = sx
  670.          neg eax
  671.          mov [_vmatrix+20],eax
  672.  
  673.          mov ax,v_vzs[esi*2]
  674.          neg ax
  675.          push eax
  676.          call _cosine
  677.          mov vcosz,eax
  678.          mov edi,eax                        ; di = cz
  679.          pop eax
  680.          call _sine
  681.          mov vsinz,eax
  682.          mov edx,eax                        ; dx = sz
  683.  
  684.          mov ax,v_vys[esi*2]
  685.          neg ax
  686.          add ax,eyeay
  687.          push eax
  688.          call _cosine
  689.          mov vcosy,eax
  690.          pop eax
  691.          call _sine
  692.          mov vsiny,eax                      ; ax = sy
  693.  
  694.          mov ebx,edx                        ; save sz
  695.  
  696.          mov ecx,eax                        ; save sy
  697.  
  698.          imul ebx                           ; bx = - sy * sz
  699.          shrd eax,edx,14
  700.          mov ebx,eax
  701.          neg ebx
  702.          mov [_vmatrix+28],ebx
  703.  
  704.          mov eax,ecx                        ; si = cz * sy
  705.          imul edi
  706.          shrd eax,edx,14
  707.          mov esi,eax
  708.          mov [_vmatrix+24],esi
  709.  
  710.          mov eax,vcosy
  711.  
  712.          imul edi                           ; di = cy * cz
  713.          shrd eax,edx,14
  714.          mov edi,eax
  715.          mov [_vmatrix+0],edi
  716.  
  717.          mov eax,vsinz
  718.          mov ecx,vcosy
  719.  
  720.          imul ecx                           ; cx = - sz * cy
  721.          shrd eax,edx,14
  722.          mov ecx,eax
  723.          neg ecx
  724.          mov [_vmatrix+4],ecx
  725.  
  726.          mov eax,ebp
  727.          imul esi
  728.          shrd eax,edx,14
  729.          mov esi,eax
  730.          neg esi
  731.          add [_vmatrix+4],esi
  732.  
  733.          mov eax,ebp
  734.          imul edi
  735.          shrd eax,edx,14
  736.          mov edi,eax
  737.          add [_vmatrix+28],edi
  738.  
  739.          mov eax,ebp
  740.          imul ebx
  741.          shrd eax,edx,14
  742.          mov ebx,eax
  743.          add [_vmatrix+0],ebx
  744.  
  745.          mov eax,ebp
  746.          imul ecx
  747.          shrd eax,edx,14
  748.          mov ecx,eax
  749.          neg ecx
  750.          add [_vmatrix+24],ecx
  751.  
  752.          mov esi,vcosx
  753.  
  754.          mov eax,vcosy
  755.          imul esi                           ; cx * cy
  756.          shrd eax,edx,14
  757.          mov [_vmatrix+32],eax
  758.  
  759.          mov eax,vsiny
  760.          imul esi                           ;-cx * sy
  761.          shrd eax,edx,14
  762.          neg eax
  763.          mov [_vmatrix+8],eax
  764.  
  765.          mov eax,vsinz
  766.          imul esi                           ; cx * sz
  767.          shrd eax,edx,14
  768.          mov [_vmatrix+12],eax
  769.  
  770.          mov eax,vcosz
  771.          imul esi                           ; cx * cz
  772.          shrd eax,edx,14
  773.          mov [_vmatrix+16],eax
  774.  
  775.          mov edi,_ecosx                      ; now perform camera x rotation,12 imuls
  776.          mov esi,_esinx
  777.          mov ebp,esi
  778.          neg ebp
  779.  
  780.          mov eax,[_vmatrix+12]
  781.          imul edi
  782.          shrd eax,edx,14
  783.          mov ecx,eax
  784.  
  785.          mov eax,[_vmatrix+24]
  786.          imul esi
  787.          shrd eax,edx,14
  788.  
  789.          add ecx,eax                        ; ecx = new _vmatrix+12
  790.  
  791.          mov eax,[_vmatrix+12]
  792.          imul ebp
  793.          shrd eax,edx,14
  794.          mov ebx,eax
  795.  
  796.          mov eax,[_vmatrix+24]
  797.          imul edi
  798.          shrd eax,edx,14
  799.  
  800.          add ebx,eax                        ; ebx = new _vmatrix+24
  801.  
  802.          mov [_vmatrix+12],ecx
  803.          mov [_vmatrix+24],ebx
  804.  
  805.          mov eax,[_vmatrix+16]
  806.          imul edi
  807.          shrd eax,edx,14
  808.          mov ecx,eax
  809.  
  810.          mov eax,[_vmatrix+28]
  811.          imul esi
  812.          shrd eax,edx,14
  813.  
  814.          add ecx,eax                        ; ecx = new _vmatrix+16
  815.  
  816.          mov eax,[_vmatrix+16]
  817.          imul ebp
  818.          shrd eax,edx,14
  819.          mov ebx,eax
  820.  
  821.          mov eax,[_vmatrix+28]
  822.          imul edi
  823.          shrd eax,edx,14
  824.  
  825.          add ebx,eax                        ; ebx = new _vmatrix+28
  826.  
  827.          mov [_vmatrix+16],ecx
  828.          mov [_vmatrix+28],ebx
  829.  
  830.          mov eax,[_vmatrix+20]
  831.          imul edi
  832.          shrd eax,edx,14
  833.          mov ecx,eax
  834.  
  835.          mov eax,[_vmatrix+32]
  836.          imul esi
  837.          shrd eax,edx,14
  838.  
  839.          add ecx,eax                        ; ecx = new _vmatrix+20
  840.  
  841.          mov eax,[_vmatrix+20]
  842.          imul ebp
  843.          shrd eax,edx,14
  844.          mov ebx,eax
  845.  
  846.          mov eax,[_vmatrix+32]
  847.          imul edi
  848.          shrd eax,edx,14
  849.  
  850.          add ebx,eax                        ; ebx = new _vmatrix+32
  851.  
  852.          mov [_vmatrix+20],ecx
  853.          mov [_vmatrix+32],ebx
  854.  
  855.          if usez eq yes
  856.          cmp eyeaz,0
  857.          je cp_noz
  858.  
  859.          mov edi,_ecosz                      ; now perform camera z rotation,12 imuls
  860.          mov esi,_esinz
  861.          mov ebp,esi
  862.          neg esi
  863.  
  864.          mov eax,[_vmatrix+0]
  865.          imul edi
  866.          shrd eax,edx,14
  867.          mov ecx,eax
  868.  
  869.          mov eax,[_vmatrix+12]
  870.          imul esi
  871.          shrd eax,edx,14
  872.  
  873.          add ecx,eax
  874.  
  875.          mov eax,[_vmatrix+0]
  876.          imul ebp
  877.          shrd eax,edx,14
  878.          mov ebx,eax
  879.  
  880.          mov eax,[_vmatrix+12]
  881.          imul edi
  882.          shrd eax,edx,14
  883.  
  884.          add ebx,eax
  885.  
  886.          mov [_vmatrix+0],ecx
  887.          mov [_vmatrix+12],ebx
  888.  
  889.          mov eax,[_vmatrix+4]
  890.          imul edi
  891.          shrd eax,edx,14
  892.          mov ecx,eax
  893.  
  894.          mov eax,[_vmatrix+16]
  895.          imul esi
  896.          shr eax,14
  897.          movsx eax,ax
  898.  
  899.          add ecx,eax
  900.  
  901.          mov eax,[_vmatrix+4]
  902.          imul ebp
  903.          shrd eax,edx,14
  904.          mov ebx,eax
  905.  
  906.          mov eax,[_vmatrix+16]
  907.          imul edi
  908.          shrd eax,edx,14
  909.  
  910.          add ebx,eax
  911.  
  912.          mov [_vmatrix+4],ecx
  913.          mov [_vmatrix+16],ebx
  914.  
  915.          mov eax,[_vmatrix+8]
  916.          imul edi
  917.          shrd eax,edx,14
  918.          mov ecx,eax
  919.  
  920.          mov eax,[_vmatrix+20]
  921.          imul esi
  922.          shrd eax,edx,14
  923.  
  924.          add ecx,eax
  925.  
  926.          mov eax,[_vmatrix+8]
  927.          imul ebp
  928.          shrd eax,edx,14
  929.          mov ebx,eax
  930.  
  931.          mov eax,[_vmatrix+20]
  932.          imul edi
  933.          shrd eax,edx,14
  934.  
  935.          add ebx,eax
  936.  
  937.          mov [_vmatrix+8],ecx
  938.          mov [_vmatrix+20],ebx
  939.  
  940.          endif
  941. cp_noz:
  942.          pop esi
  943.          ret
  944.  
  945. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  946. ;
  947. ; _setsincose - generate rotation matrix for  y,x,z  camera rotation
  948. ;
  949. ; In:
  950. ;    eyeax - camera x angle (0-65536)
  951. ;    eyeay - camera y angle (0-65536)
  952. ;    eyeaz - camera z angle (0-65536)
  953. ; Out:
  954. ;    _vmatrix - resulting rotation matrix including camera matrix
  955. ;
  956. ; Notes:
  957. ; called only once every frame.  completed in 12 multiplys
  958. ; matrix is also used for objects with no rotation (always angle 0,0,0)
  959. ;
  960. ; where is my postcard! see readme.doc for info.
  961. ;
  962. ;              x                    y                    z
  963. ;
  964. ; x=  cz * cy + sx * sy * sz     -cx * sz     - sy * cz + sx * cy * sz
  965. ;
  966. ; y=  sz * cy - sx * sy * cz      cx * cz     - sy * sz - sx * cy * cz
  967. ;
  968. ; z=         cx * sy                 sx                cx * cy
  969. ;
  970. ;
  971. ;  matrix offsets: (doublewords)
  972. ;
  973. ;     x  y  z
  974. ;
  975. ; x    0  4  8
  976. ; y   12 16 20
  977. ; z   24 28 32
  978. ;
  979. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  980.  
  981.          align 4
  982.  
  983. _setsincose:
  984.          mov ax,eyeax
  985.          call _cosine
  986.          mov _ecosx,eax                     ; _ecosx and such are used by object rotation
  987.          mov ax,eyeax                      ; _ematrix is used to find where object is
  988.          call _sine
  989.          mov _esinx,eax
  990.          mov [_ematrix+28],eax
  991.          mov ebp,eax                        ; bp = sx
  992.  
  993.          if usez eq yes
  994.          mov ax,eyeaz
  995.          call _cosine
  996.          mov _ecosz,eax
  997.          mov edi,eax                        ; di = cz
  998.          mov ax,eyeaz
  999.          call _sine
  1000.          mov _esinz,eax
  1001.          mov edx,eax                        ; dx = sz
  1002.          endif
  1003.  
  1004.          if usez eq no
  1005.          mov edi,4000h                      ; di = cos 0
  1006.          mov _ecosz,4000h
  1007.          xor edx,edx                        ; dx = sin 0
  1008.          mov _esinz,0
  1009.          endif
  1010.  
  1011.          mov ax,eyeay
  1012.          call _cosine
  1013.          mov _ecosy,eax
  1014.          mov ax,eyeay
  1015.          call _sine
  1016.          mov _esiny,eax                      ; ax = sy
  1017.  
  1018.          mov ebx,edx                        ; save sz
  1019.  
  1020.          mov ecx,eax                        ; save sy
  1021.  
  1022.          imul ebx                           ; bx = sy * sz
  1023.          shrd eax,edx,14
  1024.          mov ebx,eax
  1025.          neg ebx
  1026.          mov [_ematrix+20],ebx
  1027.          neg ebx
  1028.  
  1029.          mov eax,ecx                        ; si = - (cz * sy)
  1030.          imul edi
  1031.          shrd eax,edx,14
  1032.          mov esi,eax
  1033.          neg esi
  1034.          mov [_ematrix+8],esi
  1035.  
  1036.          mov eax,_ecosy
  1037.  
  1038.          imul edi                           ; di = cy * cz
  1039.          shrd eax,edx,14
  1040.          mov edi,eax
  1041.          mov [_ematrix+0],edi
  1042.  
  1043.          mov eax,_esinz
  1044.          mov ecx,_ecosy
  1045.  
  1046.          imul ecx                           ; cx = sz * cy
  1047.          shrd eax,edx,14
  1048.          mov ecx,eax
  1049.          mov [_ematrix+12],ecx
  1050.  
  1051.          mov eax,ebp
  1052.          imul esi
  1053.          shrd eax,edx,14
  1054.          mov esi,eax
  1055.          add [_ematrix+12],esi
  1056.  
  1057.          mov eax,ebp
  1058.          imul edi
  1059.          shrd eax,edx,14
  1060.          mov edi,eax
  1061.          neg edi
  1062.          add [_ematrix+20],edi
  1063.  
  1064.          mov eax,ebp
  1065.          imul ebx
  1066.          shrd eax,edx,14
  1067.          mov ebx,eax
  1068.          add [_ematrix+0],ebx
  1069.  
  1070.          mov eax,ebp
  1071.          imul ecx
  1072.          shrd eax,edx,14
  1073.          mov ecx,eax
  1074.          add [_ematrix+8],ecx
  1075.  
  1076.          mov esi,_ecosx
  1077.  
  1078.          mov eax,_ecosy
  1079.          imul esi                           ; cx * cy
  1080.          shrd eax,edx,14
  1081.          mov [_ematrix+32],eax
  1082.  
  1083.          mov eax,_esiny
  1084.          imul esi                           ; cx * sy
  1085.          shrd eax,edx,14
  1086.          mov [_ematrix+24],eax
  1087.  
  1088.          mov eax,_esinz
  1089.          imul esi                           ;-cx * sz
  1090.          shrd eax,edx,14
  1091.          neg eax
  1092.          mov [_ematrix+4],eax
  1093.  
  1094.          mov eax,_ecosz
  1095.          imul esi                           ; cx * cz
  1096.          shrd eax,edx,14
  1097.          mov [_ematrix+16],eax
  1098.  
  1099.          neg _esinx                         ; reverse angles for object rotation
  1100.          neg _esiny
  1101.  
  1102.          ret
  1103.  
  1104. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1105. ;
  1106. ; _temp_matrix: generate temp matrix, 12 imul's, from object esi
  1107. ;
  1108. ; In:
  1109. ;    ESI - Object # to get angles from
  1110. ;    v_vxs[esi*2] - object x angle (0-65536)
  1111. ;    v_vys[esi*2] - object y angle (0-65536)
  1112. ;    v_vzs[esi*2] - object z angle (0-65536)
  1113. ; Out:
  1114. ;    _tmatrix - resulting rotation matrix (excluding camera matrix)
  1115. ;    ESI = ESI
  1116. ;
  1117. ; Notes:
  1118. ;              x                         y                      z
  1119. ;
  1120. ;x=  cz * cy - sx * sy * sz   - sz * cy - sx * sy * cz     - cx * sy
  1121. ;
  1122. ;y=         sz * cx                   cx * cz                - sx
  1123. ;
  1124. ;z=  cz * sy + sx * sz * cy   - sy * sz + sx * cy * cz       cx * cy
  1125. ;
  1126. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1127.  
  1128. _temp_matrix:
  1129.          push esi
  1130.  
  1131.          mov ax,v_vxs[esi*2]
  1132.          neg ax
  1133.          push eax
  1134.          call _cosine
  1135.          mov vcosx,eax
  1136.          pop eax
  1137.          call _sine
  1138.          mov vsinx,eax
  1139.          mov ebp,eax                        ; bp = sx
  1140.          neg eax
  1141.          mov [_tmatrix+20],eax
  1142.  
  1143.          mov ax,v_vzs[esi*2]
  1144.          neg ax
  1145.          push eax
  1146.          call _cosine
  1147.          mov vcosz,eax
  1148.          mov edi,eax                        ; di = cz
  1149.          pop eax
  1150.          call _sine
  1151.          mov vsinz,eax
  1152.          mov edx,eax                        ; dx = sz
  1153.  
  1154.          mov ax,v_vys[esi*2]
  1155.          neg ax
  1156.          push eax
  1157.          call _cosine
  1158.          mov vcosy,eax
  1159.          pop eax
  1160.          call _sine
  1161.          mov vsiny,eax                      ; ax = sy
  1162.  
  1163.          mov ebx,edx                        ; save sz
  1164.  
  1165.          mov ecx,eax                        ; save sy
  1166.  
  1167.          imul ebx                           ; bx = - sy * sz
  1168.          shr eax,14
  1169.          movsx ebx,ax
  1170.          neg ebx
  1171.          mov [_tmatrix+28],ebx
  1172.  
  1173.          mov eax,ecx                        ; si = cz * sy
  1174.          imul edi
  1175.          shr eax,14
  1176.          movsx esi,ax
  1177.          mov [_tmatrix+24],esi
  1178.  
  1179.          mov eax,vcosy
  1180.  
  1181.          imul edi                           ; di = cy * cz
  1182.          shr eax,14
  1183.          movsx edi,ax
  1184.          mov [_tmatrix+0],edi
  1185.  
  1186.          mov eax,vsinz
  1187.          mov ecx,vcosy
  1188.  
  1189.          imul ecx                           ; cx = - sz * cy
  1190.          shr eax,14
  1191.          movsx ecx,ax
  1192.          neg ecx
  1193.          mov [_tmatrix+4],ecx
  1194.  
  1195.          mov eax,ebp
  1196.          imul esi
  1197.          shr eax,14
  1198.          movsx esi,ax
  1199.          neg esi
  1200.          add [_tmatrix+4],esi
  1201.  
  1202.          mov eax,ebp
  1203.          imul edi
  1204.          shr eax,14
  1205.          movsx edi,ax
  1206.          add [_tmatrix+28],edi
  1207.  
  1208.          mov eax,ebp
  1209.          imul ebx
  1210.          shr eax,14
  1211.          movsx ebx,ax
  1212.          add [_tmatrix+0],ebx
  1213.  
  1214.          mov eax,ebp
  1215.          imul ecx
  1216.          shr eax,14
  1217.          movsx ecx,ax
  1218.          neg ecx
  1219.          add [_tmatrix+24],ecx
  1220.  
  1221.          mov esi,vcosx
  1222.  
  1223.          mov eax,vcosy
  1224.          imul esi                           ; cx * cy
  1225.          shr eax,14
  1226.          movsx eax,ax
  1227.          mov [_tmatrix+32],eax
  1228.  
  1229.          mov eax,vsiny
  1230.          imul esi                           ;-cx * sy
  1231.          shr eax,14
  1232.          movsx eax,ax
  1233.          neg eax
  1234.          mov [_tmatrix+8],eax
  1235.  
  1236.          mov eax,vsinz
  1237.          imul esi                           ; cx * sz
  1238.          shr eax,14
  1239.          movsx eax,ax
  1240.          mov [_tmatrix+12],eax
  1241.  
  1242.          mov eax,vcosz
  1243.          imul esi                           ; cx * cz
  1244.          shr eax,14
  1245.          movsx eax,ax
  1246.          mov [_tmatrix+16],eax
  1247.  
  1248.          pop esi
  1249.          ret
  1250.  
  1251. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1252. ;
  1253. ; _temp_rotate_point - 32 bit _rotate_point point using _tmatrix
  1254. ; In:
  1255. ;    EBX - x point
  1256. ;    ECX - y point
  1257. ;    EBP - z point
  1258. ;     _tmatrix - 32 bit rotation matrix - set up by "_temp_matrix" routine
  1259. ; Out:
  1260. ;    EBX - x point
  1261. ;    ECX - y point
  1262. ;    EBP - z point
  1263. ;
  1264. ; Notes:
  1265. ;  Same as _rotate_point and _rotate_by_camera
  1266. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1267.  
  1268. _temp_rotate_point:
  1269.          mov eax,_tmatrix+8                 ; solve x = bx(0)+cx(1)+bp(2)
  1270.          imul ebp
  1271.          shrd eax,edx,14
  1272.          mov edi,eax
  1273.          mov eax,_tmatrix+4
  1274.          imul ecx
  1275.          shrd eax,edx,14
  1276.          add edi,eax
  1277.          mov eax,_tmatrix+0
  1278.          imul ebx
  1279.          shrd eax,edx,14
  1280.          add edi,eax                        ; di = new x
  1281.  
  1282.          mov eax,_tmatrix+20                ; solve y = bx(3)+cx(4)+bp(5)
  1283.          imul ebp
  1284.          shrd eax,edx,14
  1285.          mov esi,eax
  1286.          mov eax,_tmatrix+16
  1287.          imul ecx
  1288.          shrd eax,edx,14
  1289.          add esi,eax
  1290.          mov eax,_tmatrix+12
  1291.          imul ebx
  1292.          shrd eax,edx,14
  1293.          add esi,eax                        ; si = new y
  1294.  
  1295.          mov eax,_tmatrix+32                ; solve z = bx(6)+cx(7)+bp(8)
  1296.          imul ebp
  1297.          shrd eax,edx,14
  1298.          mov ebp,eax
  1299.          mov eax,_tmatrix+28
  1300.          imul ecx
  1301.          shrd eax,edx,14
  1302.          add ebp,eax
  1303.          mov eax,_tmatrix+24
  1304.          imul ebx
  1305.          shrd eax,edx,14
  1306.          add ebp,eax                        ; bp = new z
  1307.  
  1308.          mov ecx,esi
  1309.          mov ebx,edi
  1310.  
  1311.          ret
  1312.  
  1313. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1314. ;
  1315. ; _matrix_multiply: multiply _tmatrix by _vmatrix, [_vmatrix]=[_tmatrix][_vmatrix]
  1316. ;
  1317. ; In:
  1318. ;    _vmatrix - rotation matrix
  1319. ;    _tmatrix - rotation matrix
  1320. ; Out:
  1321. ;    _vmatrix - resulting rotation matrix
  1322. ;
  1323. ; Notes:
  1324. ;
  1325. ; [ _tmatrix+ 0 _tmatrix+ 2 _tmatrix+ 4 ] [ _vmatrix+ 0 _vmatrix+ 2 _vmatrix+ 4 ]
  1326. ; [                                  ] [                                  ]
  1327. ; [ _tmatrix+ 6 _tmatrix+ 8 _tmatrix+10 ] [ _vmatrix+ 6 _vmatrix+ 8 _vmatrix+10 ]
  1328. ; [                                  ] [                                  ]
  1329. ; [ _tmatrix+12 _tmatrix+14 _tmatrix+16 ] [ _vmatrix+12 _vmatrix+14 _vmatrix+16 ]
  1330. ;
  1331. ; Think of it this way, this routine will generate a resulting matrix as  if
  1332. ; you _rotate_pointd an  object by _tmatrix, then _rotate_pointd  the  object  by  _vmatrix.
  1333. ; Instead, call this routine then you will only have to _rotate_point the object by
  1334. ; _vmatrix!.
  1335. ;
  1336. ; Notice _tmatrix is done before _vmatrix!!  This is used for calculating the
  1337. ; positions of arms on bodies, hands on arms, fingers on hands...etc...
  1338. ;
  1339. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1340.  
  1341. _matrix_multiply:
  1342.  
  1343.          mov ebx,[_vmatrix+0]
  1344.          mov ecx,[_vmatrix+4]
  1345.          mov ebp,[_vmatrix+8]
  1346.  
  1347.          mov eax,[_tmatrix+0]
  1348.          imul ebx
  1349.          shrd eax,edx,14
  1350.          mov esi,eax
  1351.  
  1352.          mov eax,[_tmatrix+12]
  1353.          imul ecx
  1354.          shrd eax,edx,14
  1355.          add esi,eax
  1356.  
  1357.          mov eax,[_tmatrix+24]
  1358.          imul ebp
  1359.          shrd eax,edx,14
  1360.          add esi,eax
  1361.  
  1362.          push esi                           ; _tmatrix+0
  1363.  
  1364.          mov eax,[_tmatrix+4]
  1365.          imul ebx
  1366.          shrd eax,edx,14
  1367.          mov esi,eax
  1368.  
  1369.          mov eax,[_tmatrix+16]
  1370.          imul ecx
  1371.          shrd eax,edx,14
  1372.          add esi,eax
  1373.  
  1374.          mov eax,[_tmatrix+28]
  1375.          imul ebp
  1376.          shrd eax,edx,14
  1377.          add esi,eax
  1378.  
  1379.          push esi                           ; _tmatrix+4
  1380.  
  1381.          mov eax,[_tmatrix+8]
  1382.          imul ebx
  1383.          shrd eax,edx,14
  1384.          mov esi,eax
  1385.  
  1386.          mov eax,[_tmatrix+20]
  1387.          imul ecx
  1388.          shrd eax,edx,14
  1389.          add esi,eax
  1390.  
  1391.          mov eax,[_tmatrix+32]
  1392.          imul ebp
  1393.          shrd eax,edx,14
  1394.          add esi,eax
  1395.  
  1396.          push esi                           ; _tmatrix+8
  1397.  
  1398.          mov ebx,[_vmatrix+12]
  1399.          mov ecx,[_vmatrix+16]
  1400.          mov ebp,[_vmatrix+20]
  1401.  
  1402.          mov eax,[_tmatrix+0]
  1403.          imul ebx
  1404.          shrd eax,edx,14
  1405.          mov esi,eax
  1406.  
  1407.          mov eax,[_tmatrix+12]
  1408.          imul ecx
  1409.          shrd eax,edx,14
  1410.          add esi,eax
  1411.  
  1412.          mov eax,[_tmatrix+24]
  1413.          imul ebp
  1414.          shrd eax,edx,14
  1415.          add esi,eax
  1416.  
  1417.          push esi                           ; _tmatrix+12
  1418.  
  1419.          mov eax,[_tmatrix+4]
  1420.          imul ebx
  1421.          shrd eax,edx,14
  1422.          mov esi,eax
  1423.  
  1424.          mov eax,[_tmatrix+16]
  1425.          imul ecx
  1426.          shrd eax,edx,14
  1427.          add esi,eax
  1428.  
  1429.          mov eax,[_tmatrix+28]
  1430.          imul ebp
  1431.          shrd eax,edx,14
  1432.          add esi,eax
  1433.  
  1434.          push esi                           ; _tmatrix+16
  1435.  
  1436.          mov eax,[_tmatrix+8]
  1437.          imul ebx
  1438.          shrd eax,edx,14
  1439.          mov esi,eax
  1440.  
  1441.          mov eax,[_tmatrix+20]
  1442.          imul ecx
  1443.          shrd eax,edx,14
  1444.          add esi,eax
  1445.  
  1446.          mov eax,[_tmatrix+32]
  1447.          imul ebp
  1448.          shrd eax,edx,14
  1449.          add esi,eax
  1450.  
  1451.          push esi                           ; _tmatrix+20
  1452.  
  1453.          mov ebx,[_vmatrix+24]
  1454.          mov ecx,[_vmatrix+28]
  1455.          mov ebp,[_vmatrix+32]
  1456.  
  1457.          mov eax,[_tmatrix+0]
  1458.          imul ebx
  1459.          shrd eax,edx,14
  1460.          mov esi,eax
  1461.  
  1462.          mov eax,[_tmatrix+12]
  1463.          imul ecx
  1464.          shrd eax,edx,14
  1465.          add esi,eax
  1466.  
  1467.          mov eax,[_tmatrix+24]
  1468.          imul ebp
  1469.          shrd eax,edx,14
  1470.          add esi,eax
  1471.  
  1472.          push esi                           ; _tmatrix+24
  1473.  
  1474.          mov eax,[_tmatrix+4]
  1475.          imul ebx
  1476.          shrd eax,edx,14
  1477.          mov esi,eax
  1478.  
  1479.          mov eax,[_tmatrix+16]
  1480.          imul ecx
  1481.          shrd eax,edx,14
  1482.          add esi,eax
  1483.  
  1484.          mov eax,[_tmatrix+28]
  1485.          imul ebp
  1486.          shrd eax,edx,14
  1487.          add esi,eax
  1488.  
  1489.          push esi                           ; _tmatrix+28
  1490.  
  1491.          mov eax,[_tmatrix+8]
  1492.          imul ebx
  1493.          shrd eax,edx,14
  1494.          mov esi,eax
  1495.  
  1496.          mov eax,[_tmatrix+20]
  1497.          imul ecx
  1498.          shrd eax,edx,14
  1499.          add esi,eax
  1500.  
  1501.          mov eax,[_tmatrix+32]
  1502.          imul ebp
  1503.          shrd eax,edx,14
  1504.          add esi,eax
  1505.  
  1506. ;        push esi             ; _tmatrix+32
  1507.  
  1508. ;        pop esi
  1509.          mov [_vmatrix+32],esi
  1510.          pop esi
  1511.          mov [_vmatrix+28],esi
  1512.          pop esi
  1513.          mov [_vmatrix+24],esi
  1514.          pop esi
  1515.          mov [_vmatrix+20],esi
  1516.          pop esi
  1517.          mov [_vmatrix+16],esi
  1518.          pop esi
  1519.          mov [_vmatrix+12],esi
  1520.          pop esi
  1521.          mov [_vmatrix+ 8],esi
  1522.          pop esi
  1523.          mov [_vmatrix+ 4],esi
  1524.          pop esi
  1525.          mov [_vmatrix+ 0],esi
  1526.          ret
  1527.  
  1528. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1529. ;
  1530. ; _sqrt: Routine courtesy TRAN
  1531. ;
  1532. ; In:
  1533. ;   EAX - number to take root of
  1534. ; Out:
  1535. ;   EAX - root
  1536. ;
  1537. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1538. _sqrtbasetbl db 0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225
  1539.  
  1540.          align 4
  1541. _sqrt:
  1542.          pushad
  1543.          mov ebp,eax
  1544.          bsr ebx,eax
  1545.          jnz short _sqrtf0
  1546.          xor ebx,ebx
  1547. _sqrtf0:
  1548.          shr ebx,3
  1549.          lea eax,[ebx*8]
  1550.          mov cl,32
  1551.          sub cl,al
  1552.          rol ebp,cl
  1553.          mov eax,ebp
  1554.          movzx eax,al
  1555.          mov edi,offset _sqrtbasetbl
  1556.          mov ecx,10h
  1557. _sqrtl0:
  1558.          scasb
  1559.          je short _sqrtl0d
  1560.          jb short _sqrtl0d2
  1561.          loop _sqrtl0
  1562.          inc edi
  1563. _sqrtl0d2:
  1564.          dec edi
  1565.          inc cl
  1566. _sqrtl0d:
  1567.          movzx edx,byte ptr [edi-1]
  1568.          dec cl
  1569.          xor cl,0fh
  1570.          mov edi,ecx
  1571.          mov ecx,ebx
  1572.          jecxz short _sqrtdone
  1573.          sub eax,edx
  1574. _sqrtml:
  1575.          shld eax,ebp,8
  1576.          rol ebp,8
  1577.          mov ebx,edi
  1578.          shl ebx,5
  1579.          xor edx,edx
  1580.          mov esi,eax
  1581.          div ebx
  1582.          rol edi,4
  1583.          add edi,eax
  1584.          add ebx,eax
  1585. _sqrtf2:
  1586.          imul eax,ebx
  1587.          mov edx,eax
  1588.          mov eax,esi
  1589.          sub eax,edx
  1590.          jc short _sqrtf1
  1591.          loop _sqrtml
  1592. _sqrtdone:
  1593.          mov [esp+28],edi
  1594.          popad
  1595.          ret
  1596. _sqrtf1:
  1597.          dec ebx
  1598.          dec edi
  1599.          movzx eax,bl
  1600.          and al,1fh
  1601.          jmp _sqrtf2
  1602.  
  1603. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1604. ;
  1605. ; _lambert: generate _lambert shading 1x3 matrix, completed in 6 imuls
  1606. ;
  1607. ; In:
  1608. ;    ESI - Object # to get angles from
  1609. ;    v_vxs[esi*2] - object x angle (0-65536)
  1610. ;    v_vys[esi*2] - object y angle (0-65536)
  1611. ;    v_vzs[esi*2] - object z angle (0-65536)
  1612. ;    _y_angle_of_sun - (0-65536)
  1613. ;
  1614. ; Out:
  1615. ;    _lmatrix  - shading matrix
  1616. ;    ESI - ?
  1617. ;
  1618. ; Notes:
  1619. ;
  1620. ;z= ( sz ( cx + ( sx * cy )) + cz * sy ) * 45degrees  [x]
  1621. ;   ( cz ( cx + ( sx * cy )) - sz * sy ) * 45degrees  [y]
  1622. ;   ( cx * cy - sx ) * 45 degrees                     [z]
  1623. ;
  1624. ;note cos45=sin45=2d41h, but we will use 2d00h (99.2% accurate)
  1625. ; you can change the y angle of the sun/light but not the x angle.
  1626. ; changing the x angle would require a new formula.
  1627. ;
  1628. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1629.  
  1630. _lambert:
  1631.          mov ax,v_vxs[esi*2]
  1632.          neg ax
  1633.          push eax
  1634.          call _cosine
  1635.          mov vcosx,eax
  1636.          pop eax
  1637.          call _sine
  1638.          mov vsinx,eax
  1639.          mov ebp,eax                        ; ebp = sx
  1640.  
  1641.          mov ax,v_vzs[esi*2]
  1642.          neg ax
  1643.          push eax
  1644.          call _cosine
  1645.          mov vcosz,eax
  1646.          mov edi,eax                        ; edi = cz
  1647.          pop eax
  1648.          call _sine
  1649.          mov vsinz,eax
  1650.          mov edx,eax                        ; edx = sz
  1651.  
  1652.          mov ax,v_vys[esi*2]
  1653.          neg ax
  1654.          add eax,_y_angle_of_sun            ; 2000h = 45 degrees y angle for light source
  1655.          push eax
  1656.          call _cosine
  1657.          mov vcosy,eax
  1658.          mov esi,eax                        ; esi = cy
  1659.          pop eax
  1660.          call _sine
  1661.          mov vsiny,eax                      ; eax = sy
  1662.  
  1663.          mov ebx,edx                        ; ebx = sz
  1664.  
  1665.          mov ecx,eax                        ; ecx = sy
  1666.  
  1667.          mov eax,ebp                        ; get sx
  1668.  
  1669.          imul esi                           ; eax = sx * cy
  1670.          shrd eax,edx,14
  1671.          sub eax,vcosx                      ; eax = cx + ( sx * cy)
  1672.  
  1673.          push eax
  1674.  
  1675.          imul ebx                           ; cx + ( sx * cy) * sz
  1676.          shrd eax,edx,14
  1677.          mov _lmatrix+0,eax
  1678.  
  1679.          pop eax
  1680.  
  1681.          imul edi                           ; di = cz
  1682.          shrd eax,edx,14
  1683.          mov _lmatrix+4,eax                 ; cx + ( sx * cy) * cz
  1684.  
  1685.          mov eax,ebx
  1686.          imul ecx                           ; - sz * sy
  1687.          shrd eax,edx,14
  1688.          sub _lmatrix+4,eax
  1689.  
  1690.          mov eax,edi
  1691.          imul ecx                           ; cz * sy
  1692.          shrd eax,edx,14
  1693.          add _lmatrix+0,eax
  1694.  
  1695.          mov eax,vcosx                      ; (cx * cy - sx) * 45deg
  1696.          imul esi
  1697.          shrd eax,edx,14
  1698.          mov ebx,eax
  1699.          add ebx,ebp
  1700.  
  1701.          cmul eax,ebx,2d00h                 ; * 45degrees
  1702.          shrd eax,edx,14
  1703.          movsx eax,ax
  1704.          mov _lmatrix+8,eax
  1705.  
  1706.          mov ebx,_lmatrix+4
  1707.          cmul eax,ebx,2d00h
  1708.          shrd eax,edx,14
  1709.          mov _lmatrix+4,eax
  1710.  
  1711.          mov ebx,_lmatrix+0
  1712.          cmul eax,ebx,2d00h
  1713.          shrd eax,edx,14
  1714.          mov _lmatrix+0,eax
  1715.  
  1716.          ret
  1717.  
  1718. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1719. ;
  1720. ; _pre_cal_lambert: Pre-calculate all neccessary stuff for object DI
  1721. ;
  1722. ; In:
  1723. ;    EDI - Object # to pre-calculate normals for
  1724. ;    _objbase[esi*4] -> offset of object data
  1725. ; Out:
  1726. ;    ESI -> minimum address of object data
  1727. ;    EDI -> maximum address of object data
  1728. ;    EBP -> points to header for object
  1729. ;
  1730. ; Notes:
  1731. ;
  1732. ; Precalculate surface normals for object di.  This  is  so  you  don't
  1733. ; have to type them in when de_sineing new objects. Imagine, 400 points,
  1734. ; with 350 surfaces, calculating them all manually?  This routine  also
  1735. ; figures out the iteration skip offset (if you have surfaces dependant
  1736. ; on other surfaces) and also sets bit 1 if it is a line (two  points),
  1737. ; and sets bit 4 if 1 point.This routine also sets the number of points
  1738. ; to skip if an iteration is found. It  counts  the  number  of  points
  1739. ; within iterations (even iterations within iterations)  and  sets  the
  1740. ; skip value so any iterations skipped will have a pre-calculated point
  1741. ; offset.  Did that make sense?
  1742. ;
  1743. ; Things done here:
  1744. ;
  1745. ; set point command if only 1 connection
  1746. ; set line  command if only 2 connections
  1747. ; set normal bit in commands if shading used in texture
  1748. ; calculate and set shading normals
  1749. ; calculate offsets for iteration jumps (in case surface not visible)
  1750. ; calculate number of points to skip for iterations (in case surface not visible)
  1751. ; set offset flag if iteration uses a point offset (4'th future use word)
  1752. ; calculate and set auto-intensity of color if auto_s bit set
  1753. ;
  1754. ; Most of the above is done so the user (you) wont have to calculate this stuff
  1755. ; yourself - makes object modification much easier.
  1756. ;
  1757. ; If you find the routine to be sloppy remember it is only used
  1758. ; for object initialization.
  1759. ;
  1760. ; This routine  will probably crash if your object is not set up correctly
  1761. ; The entire 3dvect source will crash if this routine  isn't run  and  the
  1762. ; chances of you knowing how to do all that  this  routine  does  manually
  1763. ; are pretty slim since most of you out there are doughheads.
  1764. ;
  1765. ; The minimum and maximum addresses are returned in ESI and EDI so you can
  1766. ; output the resulting object to a binary file. EBP points to the starting
  1767. ; header of the object (usually, but not neccessaraly, the minimum address)
  1768. ;
  1769. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1770.  
  1771. _lx1     dd 0
  1772. _ly1     dd 0
  1773. _lz1     dd 0
  1774.  
  1775. _lx2     dd 0
  1776. _ly2     dd 0
  1777. _lz2     dd 0
  1778.  
  1779. _lx3     dd 0
  1780. _ly3     dd 0
  1781. _lz3     dd 0
  1782.  
  1783. finx     dd 0
  1784. finy     dd 0
  1785. finz     dd 0
  1786.  
  1787. temp1    dw 0
  1788. temp2    dw 0                               ; number of points
  1789. temp3    dw 0                               ; number of sides
  1790. temp4    dw 0
  1791. temp5    dd 0                               ; minimum address
  1792. temp6    dd 0                               ; maximum address
  1793.  
  1794. _pre_cal_lambert:
  1795.          movzx edi,di                       ; in case user is lazy
  1796.          mov esi,_objbase[edi*4]
  1797.          mov temp5,esi
  1798.          mov temp6,esi
  1799.          push esi                           ; save for exit
  1800. more_reses:
  1801.          push esi                           ; save header offset
  1802.          add esi,4
  1803.          lodsd
  1804.          add esi,eax                        ; handle first resolution
  1805.  
  1806.          lodsw
  1807.          mov temp2,ax
  1808.          lodsw
  1809.          mov temp3,ax
  1810.  
  1811.          mov xad,0
  1812.          mov yad,0
  1813.          mov zad,0
  1814.          mov temp1,-1
  1815.          mov ax,[esi+14]
  1816.          mov temp4,ax
  1817.  
  1818.          mov eax,[esi+8*2]
  1819.          or eax,[esi+8*2+4]
  1820.          jnz lam_hhgg
  1821.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  1822.          mov dword ptr [esi+8*2+4],minz
  1823. lam_hhgg:
  1824.          mov eax,[esi+12*2]
  1825.          jnz lam_hhgc
  1826.          mov dword ptr [esi+12*2],tolerance
  1827. lam_hhgc:
  1828.          add esi,25*2                       ; skip future use bytes
  1829.          mov edi,4                          ; edi=4 to skip center of gravity
  1830.          mov xp,0
  1831.          mov yp,0
  1832.          mov zp,0
  1833.          cmp temp2,0
  1834.          je no_points_2
  1835. lam_ap12:
  1836.          mov bx,w [esi]                     ; load all the points into array
  1837.          mov cx,w [esi+2]
  1838.          mov bp,w [esi+4]
  1839.          add bx,w xad
  1840.          add cx,w yad
  1841.          add bp,w zad
  1842.          movsx ebx,bx
  1843.          movsx ecx,cx
  1844.          movsx ebp,bp
  1845.          mov xp[edi],ebx
  1846.          mov yp[edi],ecx
  1847.          mov zp[edi],ebp
  1848.          add esi,6
  1849.          add edi,4
  1850.          dec temp2
  1851.          jne s lam_ap12                     ; esi = address of sides now...
  1852. no_points_2:
  1853.          mov pointindex,edi
  1854.  
  1855. lam_loadsides:
  1856.          call checkesi                      ; check minimum and maximum addresses
  1857.  
  1858.          mov edi,esi                        ; save in case of line adjust
  1859.          mov ax,[esi]                       ; get command
  1860.  
  1861.          mov bx,ax                          ; save command
  1862.          test ax,special                    ; test if special command
  1863.          jz s lam_notmap                    ; no, skip through loop
  1864.          mov di,ax
  1865.          and edi,special-1
  1866.  
  1867.          cmp ax,gosub                       ; check for jump commands, yeah,yeah, I should have made a table, who cares...
  1868.          jne ffgg1
  1869.          add esi,2
  1870.          lodsw
  1871.          push esi
  1872.          movsx eax,ax
  1873.          sub esi,2
  1874.          add esi,eax
  1875.          jmp lam_next
  1876. ffgg1:
  1877.          cmp ax,return
  1878.          jne ffgg2
  1879.          pop esi
  1880.          jmp lam_next
  1881. ffgg2:
  1882.          cmp ax,goto_offset
  1883.          jne ffgg3
  1884.          add esi,2
  1885.          lodsw
  1886.          movsx eax,ax
  1887.          sub esi,2
  1888.          add esi,eax
  1889.          jmp lam_next
  1890. ffgg3:
  1891.          mov di,number_ofb[edi*2]           ; yes, skip special command length
  1892.          add esi,edi
  1893.          xor bx,bx
  1894.          cmp ax,sub_object
  1895.          je lam_do_it
  1896.          cmp ax,static_sub_object
  1897.          je lam_do_it
  1898.          jmp lam_next                       ; go to next side
  1899. lam_notmap:
  1900.          call pcl_testashade
  1901.  
  1902.          mov ax,[esi+2]                     ; get texture for both sides
  1903.          or ax,[esi+4]
  1904.  
  1905.          test ax,shade                      ; test shading bit
  1906.          jnz lam_calcit                     ; yes, calculate shading normal
  1907.  
  1908.          push edi                           ; save command location
  1909.  
  1910.          add esi,4+4+2                      ; skip 2 colour & 2 texture words & command
  1911.          mov edi,esi
  1912.  
  1913.          lodsw                              ; get first point indexer
  1914.          add ax,temp4
  1915.          stosw
  1916.  
  1917.          mov cx,ax
  1918.          xor dx,dx
  1919. lam_ldlp:
  1920.          lodsw                              ; count number of connection points
  1921.          add ax,temp4
  1922.          stosw
  1923.  
  1924.          inc dx
  1925.          cmp ax,cx
  1926.          jne lam_ldlp
  1927.  
  1928.          call checkesi                      ; check minimum and maximum addresses
  1929.  
  1930.          pop edi                            ; pop command location
  1931.  
  1932.          cmp dx,1                           ; only 1 point?, set point command
  1933.          jne lam_test_line
  1934.          or w [edi+0],both
  1935.          or w [edi+2],point
  1936.          or w [edi+4],point
  1937.          jmp lam_test_iteration
  1938.  
  1939. lam_test_line:
  1940.          cmp dx,2                           ; only 2 points?, set line command
  1941.          jne lam_test_iteration
  1942.          or w [edi+0],both
  1943.          or w [edi+2],line
  1944.          or w [edi+4],line
  1945.  
  1946. lam_test_iteration:
  1947.          xor ax,ax
  1948.          test bx,iterate                    ; test if iteration command used
  1949.          jnz lam_do_it                      ; yes,solve internal iteration
  1950. lam_next:
  1951.          dec temp1
  1952.          jnz lam_nopop
  1953.          pop ax
  1954.          mov temp4,ax
  1955.          pop ax
  1956.          mov temp1,ax
  1957.          jmp lam_next
  1958. lam_nopop:
  1959.          dec temp3
  1960.          jnz lam_loadsides
  1961.  
  1962.          pop esi
  1963.          lodsd
  1964.          add esi,4
  1965.          cmp eax,-1                         ; last resolution?
  1966.          jne more_reses
  1967.  
  1968.          call checkesi                      ; check minimum and maximum addresses
  1969.          pop ebp                            ; pop header offset
  1970.          mov esi,temp5                      ; load up start and end offsets of object
  1971.          mov edi,temp6
  1972.  
  1973.          ret
  1974.  
  1975. lam_calcit:
  1976.          push esi                           ; save command location
  1977.          add esi,4+4+2                      ; skip colour and 2 future use words
  1978.  
  1979.          lodsw                              ; first point
  1980.          add ax,temp4
  1981.          mov [esi-2],ax
  1982.          push ax
  1983.          movzx edi,ax
  1984.  
  1985.          mov ebx,[xp+edi*4]
  1986.          mov ecx,[yp+edi*4]
  1987.          mov ebp,[zp+edi*4]
  1988.  
  1989.          mov _lx1,ebx
  1990.          mov _ly1,ecx
  1991.          mov _lz1,ebp
  1992.  
  1993.          lodsw                              ; second point
  1994.          add ax,temp4
  1995.          mov [esi-2],ax
  1996.          movzx edi,ax
  1997.  
  1998.          mov ebx,[xp+edi*4]
  1999.          mov ecx,[yp+edi*4]
  2000.          mov ebp,[zp+edi*4]
  2001.  
  2002.          mov _lx2,ebx
  2003.          mov _ly2,ecx
  2004.          mov _lz2,ebp
  2005.  
  2006.          lodsw                              ; third point
  2007.          add ax,temp4
  2008.          mov [esi-2],ax
  2009.          movzx edi,ax
  2010.  
  2011.          mov ebx,[xp+edi*4]
  2012.          mov ecx,[yp+edi*4]
  2013.          mov ebp,[zp+edi*4]
  2014.  
  2015.          mov _lx3,ebx
  2016.          mov _ly3,ecx
  2017.          mov _lz3,ebp
  2018.  
  2019.          push esi
  2020.  
  2021.          call _calc_normal
  2022.  
  2023.          pop esi
  2024.  
  2025.          pop dx                             ; now find shading normal storage, pop first connector
  2026.  
  2027. lam_ldl2:
  2028.          lodsw
  2029.          add ax,temp4
  2030.          mov [esi-2],ax
  2031.          cmp ax,dx
  2032.          jne lam_ldl2
  2033.  
  2034.          mov edi,esi
  2035.  
  2036.          mov ax,bx
  2037.          stosw
  2038.          mov ax,cx
  2039.          stosw
  2040.          mov ax,bp
  2041.          stosw
  2042.  
  2043.          add esi,6
  2044.  
  2045.          pop edi                            ; get original command location back
  2046.          or w [edi],normal
  2047.          mov bx,[edi]
  2048.          jmp lam_test_iteration
  2049.  
  2050. lam_surfc_cnt dw 0
  2051.  
  2052. ; this finds the total number of points to skip if an iteration fails, dx = #
  2053. ; remember, this is a pre-calculation routine so it doesn't need to be fast.
  2054.  
  2055. lam_do_it:
  2056.          xor dx,dx                          ; clear total number of points to skip
  2057.  
  2058.          mov ax,[esi+10]                    ; test if there is a center of rotation point
  2059.          or ax,[esi+12]
  2060.          or ax,[esi+14]
  2061.          jz done_alter2
  2062.          or w [esi+8],centroid              ; set flag if offset found (center of gravity)
  2063.  
  2064.          movsx ebx,w [esi+10]
  2065.          movsx ecx,w [esi+12]
  2066.          movsx ebp,w [esi+14]
  2067.          add xad,ebx
  2068.          add yad,ecx
  2069.          add zad,ebp
  2070.          mov ebx,xad
  2071.          mov ecx,yad
  2072.          mov ebp,zad
  2073.          mov edi,pointindex
  2074.          mov xp[edi],ebx
  2075.          mov yp[edi],ecx
  2076.          mov zp[edi],ebp
  2077.          add pointindex,2
  2078.          add dx,1                           ; centroid is an extra point to skip
  2079. done_alter2:
  2080.          mov ax,temp1
  2081.          push ax
  2082.          mov ax,temp4
  2083.          push ax
  2084.  
  2085.          mov ax,[esi+18]
  2086.          add temp4,ax
  2087.          mov w [esi+18],0
  2088.  
  2089.          mov lam_surfc_cnt,0
  2090.          push esi                           ; this is our return address (continue from here+4)
  2091.  
  2092.          lodsw                              ; get number of points.
  2093.          add dx,ax                          ; save as TOTAL number of points to skip
  2094.          mov temp2,ax
  2095.  
  2096.          lodsw                              ; get number of surfaces
  2097.          mov temp1,ax
  2098.          inc temp1
  2099.          add lam_surfc_cnt,ax               ; count until this is zero
  2100.  
  2101.          mov eax,[esi+8*2]
  2102.          or eax,[esi+10*2]
  2103.          jnz lam_hhgg2
  2104.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  2105.          mov dword ptr [esi+8*2+4],minz
  2106. lam_hhgg2:
  2107.          mov eax,[esi+12*2]
  2108.          jnz lam_hhgl
  2109.          mov dword ptr [esi+12*2],tolerance
  2110. lam_hhgl:
  2111.          add esi,25*2
  2112.  
  2113.          mov edi,pointindex
  2114.          cmp temp2,0
  2115.          je lam_test_check                  ; only sides added, no additional points
  2116. lam_ap13:
  2117.          mov bx,w [esi]                     ; load all the points into array
  2118.          mov cx,w [esi+2]                   ; for calculation of gourad shadings
  2119.          mov bp,w [esi+4]
  2120.          add bx,w xad
  2121.          add cx,w yad
  2122.          add bp,w zad
  2123.          movsx ebx,bx
  2124.          movsx ecx,cx
  2125.          movsx ebp,bp
  2126.          mov xp[edi],ebx
  2127.          mov yp[edi],ecx
  2128.          mov zp[edi],ebp
  2129.          add esi,6
  2130.          add edi,4
  2131.          dec temp2
  2132.          jne s lam_ap13                     ; esi = address of sides now...
  2133.  
  2134.          mov pointindex,edi
  2135.  
  2136. lam_test_check:
  2137.          cmp lam_surfc_cnt,0                ; test if user just wants to add points
  2138.          je lam_no_surfs                    ; i dont know why anyone would want to do this?
  2139.  
  2140. lam_test_until_target:
  2141.          lodsw                              ; get command
  2142.          mov bx,ax
  2143.          test ax,special                    ; test if special command
  2144.          jz s lam_notmap_it                 ; no, skip through loop
  2145.  
  2146.          mov di,ax
  2147.          and edi,special-1
  2148.  
  2149.          cmp ax,gosub                       ; check for jump commands, yeah,yeah, I should have made a table, who cares...
  2150.          jne ffgg1x
  2151.          add esi,2
  2152.          lodsw
  2153.          push esi
  2154.          movsx eax,ax
  2155.          sub esi,2
  2156.          add esi,eax
  2157.          jmp lam_next_it
  2158. ffgg1x:
  2159.          cmp ax,return
  2160.          jne ffgg2x
  2161.          pop esi
  2162.          jmp lam_next_it
  2163. ffgg2x:
  2164.          cmp ax,goto_offset
  2165.          jne ffgg3x
  2166.          add esi,2
  2167.          lodsw
  2168.          movsx eax,ax
  2169.          sub esi,2
  2170.          add esi,eax
  2171.          jmp lam_next_it
  2172. ffgg3x:
  2173.          movzx edi,number_ofb[edi*2]        ; yes, skip special command length
  2174.          add esi,edi
  2175.          sub esi,2
  2176.          cmp ax,sub_object
  2177.          je lam_re_lam
  2178.          cmp ax,static_sub_object
  2179.          je lam_re_lam
  2180.          jmp s lam_nog
  2181.  
  2182. lam_notmap_it:
  2183.          lodsw
  2184.          mov bp,ax
  2185.          lodsw
  2186.          or bp,ax                           ; find if shading bit used, add esi,6 if so
  2187.          add esi,4                          ; skip 2 colour words
  2188.  
  2189.          lodsw                              ; get first point indexer
  2190.          mov cx,ax
  2191. lam_ldl3:
  2192.          lodsw
  2193.          cmp ax,cx
  2194.          jne lam_ldl3
  2195.  
  2196.          test bp,shade                      ; test if gouraud normal present
  2197.          jz lam_nog
  2198.          add esi,6                          ; skip it if present
  2199. lam_nog:
  2200.          test bx,iterate                    ; test if iteration command used
  2201.          jnz lam_re_lam                     ; solve internal iteration again...
  2202. lam_next_it:
  2203.          dec lam_surfc_cnt
  2204.          jnz lam_test_until_target
  2205. lam_no_surfs:
  2206.          mov edi,esi                        ; save current location
  2207.          pop esi                            ; return original start location
  2208.          sub edi,esi                        ; get difference between them
  2209.          sub di,8                           ; offset for loadsides routine - constant
  2210.  
  2211.          lodsw                              ; get number of points
  2212.          mov bx,ax
  2213.  
  2214.          lodsw
  2215.          add temp3,ax
  2216.  
  2217.          mov cx,dx
  2218.          mov ax,6
  2219.          imul bx
  2220.          movzx ebx,ax
  2221.  
  2222.          mov ax,di
  2223.          mov edi,esi
  2224.          stosw                              ; save offset
  2225.          mov ax,cx
  2226.          stosw                              ; save number of points found in iterations
  2227.  
  2228.          mov eax,[esi+8*2]
  2229.          or eax,[esi+10*2]
  2230.          jnz lam_hhgg3
  2231.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  2232.          mov dword ptr [esi+8*2+4],minz
  2233. lam_hhgg3:
  2234.          mov eax,[esi+12*2]
  2235.          jnz lam_hhgq
  2236.          mov dword ptr [esi+12*2],tolerance
  2237. lam_hhgq:
  2238.          add esi,25*2                       ; adjust for next load
  2239.          add esi,ebx
  2240.  
  2241.          jmp lam_next
  2242.  
  2243. lam_re_lam:
  2244.          lodsw                              ; get number of points for recursed iteration
  2245.          add dx,ax                          ; save as TOTAL number of points to skip
  2246.          mov cx,ax
  2247.  
  2248.          lodsw                              ; get number of surfaces
  2249.          add lam_surfc_cnt,ax               ; count until this is zero
  2250.  
  2251.          mov eax,[esi+8*2]
  2252.          or eax,[esi+10*2]
  2253.          jnz lam_hhgg4
  2254.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  2255.          mov dword ptr [esi+8*2+4],minz
  2256. lam_hhgg4:
  2257.          mov eax,[esi+12*2]
  2258.          jnz lam_hhgv
  2259.          mov dword ptr [esi+12*2],tolerance
  2260. lam_hhgv:
  2261.          add esi,25*2
  2262.  
  2263.          mov eax,6
  2264.          imul cx
  2265.          add esi,eax
  2266.  
  2267.          jmp lam_next_it
  2268.  
  2269. checkesi:
  2270.          cmp esi,temp5
  2271.          jae noesi1
  2272.          mov temp5,esi
  2273. noesi1:
  2274.          cmp esi,temp6
  2275.          jbe noesi2
  2276.          mov temp6,esi
  2277. noesi2:
  2278.          ret
  2279.  
  2280. pcl_testashade:
  2281.          mov ax,[esi+2]
  2282.          or ax,[esi+4]
  2283.          test ax,auto_s
  2284.          jnz pcl_test2
  2285.          ret
  2286. pcl_test2:
  2287.          pushad
  2288.          push esi
  2289.          push esi
  2290.          mov _vxs,0
  2291.          mov _vys,0
  2292.          mov _vzs,0
  2293.          xor esi,esi
  2294.          call _lambert
  2295.          pop esi
  2296.  
  2297.          movzx ebx,w [esi+10]
  2298.          movzx ecx,w [esi+12]
  2299.          movzx edx,w [esi+14]
  2300.  
  2301.          mov eax,xp[ebx*4]
  2302.          mov _lx1,eax
  2303.          mov eax,yp[ebx*4]
  2304.          mov _ly1,eax
  2305.          mov eax,zp[ebx*4]
  2306.          mov _lz1,eax
  2307.          mov eax,xp[ecx*4]
  2308.          mov _lx2,eax
  2309.          mov eax,yp[ecx*4]
  2310.          mov _ly2,eax
  2311.          mov eax,zp[ecx*4]
  2312.          mov _lz2,eax
  2313.          mov eax,xp[edx*4]
  2314.          mov _lx3,eax
  2315.          mov eax,yp[edx*4]
  2316.          mov _ly3,eax
  2317.          mov eax,zp[edx*4]
  2318.          mov _lz3,eax
  2319.          call _calc_normal
  2320.  
  2321.          call _l_rotate_point
  2322.          pop esi
  2323.          push edi
  2324.  
  2325.          test w [esi+2],auto_s
  2326.          jz pcl_test4
  2327.          test w [esi+2],inverse
  2328.          jz pcl_test3
  2329.          neg edi
  2330. pcl_test3:
  2331.          add edi,256
  2332.          shr edi,1                          ; result -256 to +256, turn into 0-256
  2333.          mov al,b shading_tables[edi]       ; now into 0-15
  2334.          xor ah,ah
  2335.          add w [esi+6],ax
  2336.          mov ax,[esi+2]
  2337.          and ax,65535-auto_s
  2338.          mov [esi+2],ax
  2339. pcl_test4:
  2340.          pop edi
  2341.  
  2342.          test w [esi+4],auto_s
  2343.          jz pcl_test6
  2344.          test w [esi+4],inverse
  2345.          jz pcl_test5
  2346.          neg edi
  2347. pcl_test5:
  2348.          add edi,256
  2349.          shr edi,1                          ; result -256 to +256, turn into 0-256
  2350.          mov al,b shading_tables[edi]       ; now into 0-15
  2351.          xor ah,ah
  2352.          add w [esi+8],ax
  2353.          mov ax,[esi+4]
  2354.          and ax,65535-auto_s
  2355.          mov [esi+4],ax
  2356. pcl_test6:
  2357.          popad
  2358.          ret
  2359.  
  2360. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2361. ;
  2362. ; _calc_normal: calculate surface normal
  2363. ;
  2364. ; In:
  2365. ;    _lx1 - x of point 1 on triangle
  2366. ;    _ly1 - y of point 1 on triangle
  2367. ;    _lz1 - z of point 1 on triangle
  2368. ;    _lx2 - x of point 2 on triangle
  2369. ;    _ly2 - y of point 2 on triangle
  2370. ;    _lz2 - z of point 2 on triangle
  2371. ;    _lx3 - x of point 3 on triangle
  2372. ;    _ly3 - y of point 3 on triangle
  2373. ;    _lz3 - z of point 3 on triangle
  2374. ;
  2375. ; Out:
  2376. ;    EBX = finx = x of surface normal of triangle
  2377. ;    ECX = finy = y of surface normal of triangle
  2378. ;    EBP = finz = z of surface normal of triangle
  2379. ;
  2380. ; Notes:
  2381. ; _x2 = _x2 - _x1
  2382. ; _y2 = _y2 - _y1
  2383. ; z2 = z2 - z1
  2384. ;
  2385. ; x3 = x3 - _x1
  2386. ; y3 = y3 - _y1
  2387. ; z3 = z3 - z1
  2388. ;
  2389. ; x = _y2 * z3 - z2 * y3
  2390. ; y = z2 * x3 - _x2 * z3
  2391. ; z = _x2 * y3 - _y2 * x3
  2392. ;
  2393. ; a = SQR(x ^ 2 + y ^ 2 + z ^ 2)
  2394. ;
  2395. ; x = INT(x / a * 256 + .5)
  2396. ; y = INT(y / a * 256 + .5)
  2397. ; z = INT(z / a * 256 + .5)
  2398. ;
  2399. ; This worked for me on the first try!
  2400. ;
  2401. ; If you wanted to get the equation of a plane, you could do this after:
  2402. ;  d = - x * _x1 - y * _y1 - z * z1
  2403. ;
  2404. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2405.  
  2406.          nshl = 8
  2407.  
  2408. _calc_normal:
  2409.          mov ebx,_lx1
  2410.          mov ecx,_ly1
  2411.          mov ebp,_lz1
  2412.  
  2413.          sub _lx2,ebx
  2414.          sub _ly2,ecx
  2415.          sub _lz2,ebp
  2416.  
  2417.          sub _lx3,ebx
  2418.          sub _ly3,ecx
  2419.          sub _lz3,ebp
  2420.  
  2421.          mov eax,_ly2
  2422.          mov ebx,_lz3
  2423.          imul ebx
  2424.          mov ecx,eax
  2425.  
  2426.          mov eax,_lz2
  2427.          mov ebx,_ly3
  2428.          imul ebx
  2429.          sub ecx,eax
  2430.  
  2431.          mov finx,ecx                       ; save x of normal
  2432.  
  2433.          mov eax,_lz2
  2434.          mov ebx,_lx3
  2435.          imul ebx
  2436.          mov ecx,eax
  2437.  
  2438.          mov eax,_lx2
  2439.          mov ebx,_lz3
  2440.          imul ebx
  2441.          sub ecx,eax
  2442.  
  2443.          mov finy,ecx                       ; save y of normal
  2444.  
  2445.          mov eax,_lx2
  2446.          mov ebx,_ly3
  2447.          imul ebx
  2448.          mov ecx,eax
  2449.  
  2450.          mov eax,_ly2
  2451.          mov ebx,_lx3
  2452.          imul ebx
  2453.          sub ecx,eax
  2454.  
  2455.          mov finz,ecx                       ; save z of normal
  2456.  
  2457. calc_testloop:
  2458.          cmp finx,32768                     ; make sure (normal^2)*2 is < 2^32
  2459.          jge calc_shrit
  2460.          cmp finy,32768
  2461.          jge calc_shrit
  2462.          cmp finz,32768
  2463.          jge calc_shrit
  2464.  
  2465.          cmp finx,-32768
  2466.          jle calc_shrit
  2467.          cmp finy,-32768
  2468.          jle calc_shrit
  2469.          cmp finz,-32768
  2470.          jg ok_2_bite_dust
  2471.  
  2472. calc_shrit:
  2473.          shr finx,1                         ; calculations will be too large if squared, div by 2
  2474.          test finx,40000000h
  2475.          jz no_neg_calc1
  2476.          or finx,80000000h
  2477. no_neg_calc1:
  2478.          shr finy,1
  2479.          test finy,40000000h
  2480.          jz no_neg_calc2
  2481.          or finy,80000000h
  2482. no_neg_calc2:
  2483.          shr finz,1
  2484.          test finz,40000000h
  2485.          jz no_neg_calc3
  2486.          or finz,80000000h
  2487. no_neg_calc3:
  2488.          jmp calc_testloop
  2489.  
  2490. ok_2_bite_dust:
  2491.          mov eax,finx                       ; x^2
  2492.          mov edi,eax                        ; objects
  2493.          imul edi
  2494.          mov edi,eax
  2495.  
  2496.          mov eax,finy                       ; y^2
  2497.          mov esi,eax
  2498.          imul esi
  2499.          mov esi,eax
  2500.  
  2501.          mov eax,finz                       ; z^2
  2502.          mov ebp,eax
  2503.          imul ebp
  2504.  
  2505.          add eax,esi
  2506.          add eax,edi
  2507.  
  2508.          call _sqrt                         ; get square root of number
  2509.  
  2510.          mov ecx,eax
  2511.          or ecx,ecx
  2512.          je lam_abort                       ; should never happen!
  2513.  
  2514.          mov eax,finx
  2515.          cdq
  2516.          shl eax,nshl                       ; set unit vector to 2^nshl (256)
  2517.          idiv ecx
  2518.          mov finx,eax
  2519.  
  2520.          mov eax,finy
  2521.          cdq
  2522.          shl eax,nshl
  2523.          idiv ecx
  2524.          mov finy,eax
  2525.  
  2526.          mov eax,finz
  2527.          cdq
  2528.          shl eax,nshl
  2529.          idiv ecx
  2530.          mov finz,eax
  2531.  
  2532.          mov ebx,finx
  2533.          mov ecx,finy
  2534.          mov ebp,finz
  2535.  
  2536. lam_abort:
  2537.          ret
  2538.  
  2539. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2540. ; _calc_d: Calculate D portion of equation of a plane
  2541. ; In:
  2542. ;    EBX = x of surface normal of triangle
  2543. ;    ECX = y of surface normal of triangle
  2544. ;    EBP = z of surface normal of triangle
  2545. ;    _lx1 - x of point on triangle (any point)
  2546. ;    _ly1 - y of point on triangle
  2547. ;    _lz1 - z of point on triangle
  2548. ; Out:
  2549. ;    EAX = D     (Ax+By+Cz=D)
  2550. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2551. _calc_d:
  2552.          mov eax,_lx1
  2553.          imul ebx
  2554.          mov esi,eax
  2555.  
  2556.          mov eax,_ly1
  2557.          imul ecx
  2558.          add esi,eax
  2559.  
  2560.          mov eax,_lz1
  2561.          imul ebp
  2562.          add eax,esi
  2563.  
  2564.          ret
  2565.  
  2566. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2567. ;
  2568. ; _set_up_all_lambert: set up all _lambert normals from object si to object di
  2569. ;
  2570. ; In:
  2571. ;    ESI - object # to start at
  2572. ;    EDI - object # to end at
  2573. ;    _objbase[esi*4 - edi*4] -> offsets to object data
  2574. ; Out:
  2575. ;   null
  2576. ;
  2577. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2578.  
  2579. _set_up_all_lambert:
  2580.          movzx edi,di                       ; in case user is lazy
  2581.          movzx esi,si
  2582.  
  2583.          xchg edi,esi                       ; so user doesn't get confuzed
  2584. set_lop:
  2585.          push esi edi
  2586.          call _pre_cal_lambert
  2587.          pop edi esi
  2588.          inc edi
  2589.          cmp edi,esi
  2590.          jna set_lop
  2591.  
  2592.          ret
  2593.  
  2594. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2595. ;
  2596. ; _l_rotate_point: _rotate_point surface normal through _lambert matrix
  2597. ;
  2598. ; In:
  2599. ;    BX - x of surface normal
  2600. ;    CX - y of surface normal
  2601. ;    BP - z of surface normal
  2602. ;    _lmatrix - 16 bit, 1x3 _lambert shading matrix - set up by "_lambert" routine
  2603. ; Out:
  2604. ;    BX - x of surface normal (untouched)
  2605. ;    CX - y of surface normal (untouched)
  2606. ;    BP - z of surface normal (untouched)
  2607. ;   EDI - colour intensity for surface (-255 to +255)
  2608. ;
  2609. ; Notes:
  2610. ;   Your mother is a hamster.
  2611. ;
  2612. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2613.  
  2614. _l_rotate_point:
  2615.          mov eax,_lmatrix+8                 ; solve edi = bx(0)+cx(4)+bp(8)
  2616.          imul bp
  2617.          shrd ax,dx,14
  2618.          mov edi,eax
  2619.          mov eax,_lmatrix+4
  2620.          imul cx
  2621.          shrd ax,dx,14
  2622.          add edi,eax
  2623.          mov eax,_lmatrix+0
  2624.          imul bx
  2625.          shrd ax,dx,14
  2626.          add edi,eax                        ; di = new colour -256 to 255 (not edi, di!)
  2627.          movsx edi,di
  2628.  
  2629.          add edi,256                        ; make sure result is within range -256 to 256
  2630.          and edi,511                        ; sometimes is messes up...
  2631.          sub edi,256
  2632.  
  2633.          ret
  2634.  
  2635. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2636. ;
  2637. ; Shading tables used for fake cosin colour intensity - 256 bytes
  2638. ; Default is 16 colours per _lambert calculation.  But you could have 32, 48
  2639. ; or whatever you want, even an odd number like 53.  Use the SHADING.BAS
  2640. ; program to make the table to your custom size.
  2641. ;
  2642. ; Shading_bits is the variable for use with the texture command "LAST".  This
  2643. ; variable tells the routine what bits to  pluck  off  when  determining  the
  2644. ; shading intensity. Obviosly this cant  be  used  if  your  palette  shading
  2645. ; length is not a function of 2's complement.
  2646. ;
  2647. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2648.  
  2649.          if shading_colours eq 16
  2650.  
  2651. ; 16 colour shading table
  2652.  
  2653.          align 4
  2654. shading_tables:
  2655.          db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
  2656.          db 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2
  2657.          db 2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3
  2658.          db 3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4
  2659.          db 4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5
  2660.          db 5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6
  2661.          db 6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7
  2662.          db 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  2663.          db 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
  2664.          db 8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9
  2665.          db 9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10
  2666.          db 10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11
  2667.          db 11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12
  2668.          db 12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13
  2669.          db 13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14
  2670.          db 14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15
  2671.  
  2672.          elseif shading_colours eq 32
  2673.  
  2674. ; 32 colour shading table
  2675.  
  2676.          align 4
  2677. shading_tables:
  2678.          db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2
  2679.          db 2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4
  2680.          db 4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6
  2681.          db 6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8
  2682.          db 8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10
  2683.          db 10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12
  2684.          db 12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14
  2685.          db 14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15
  2686.          db 16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17
  2687.          db 17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19
  2688.          db 19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21
  2689.          db 21,21,21,22,22,22,22,22,22,22,22,22,23,23,23,23
  2690.          db 23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25
  2691.          db 25,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27
  2692.          db 27,27,27,28,28,28,28,28,28,28,29,29,29,29,29,29
  2693.          db 29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31
  2694.          endif
  2695.  
  2696. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2697. ;
  2698. ; Generate null Y matrix (for camera)
  2699. ;
  2700. ; In: ECX => matrix for storage
  2701. ; Out:
  2702. ;     ECX => 9 doubleword resulting rotation matrix (excluding camera y angle)
  2703. ;
  2704. ; Notes:
  2705. ;      x       y           z
  2706. ;
  2707. ; x=  cz   -cx * sz   + sx * sz
  2708. ;
  2709. ; y=  sz    cx * cz   - sx * cz
  2710. ;
  2711. ; z=   0       sx         cx
  2712. ;
  2713. ;
  2714. ;  Matrix offsets: (doublewords)
  2715. ;
  2716. ;     x  y  z
  2717. ;
  2718. ; x    0  4  8
  2719. ; y   12 16 20
  2720. ; z   24 28 32
  2721. ;
  2722. ; Notes: This routine generates the camera matrix without the Y component.
  2723. ;
  2724. ;        A call to _setsincose MUST have taken place for this routine to work
  2725. ;        correctly!
  2726. ;
  2727. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2728.  
  2729.          align 4
  2730.  
  2731. _null_y_matrix:
  2732.          mov eax,_ecosz
  2733.          mov [ecx+0],eax
  2734.  
  2735.          mov ebx,_esinz
  2736.          mov [ecx+12],ebx
  2737.  
  2738.          mov edi,_esinx
  2739.          mov [ecx+28],edi
  2740.  
  2741.          mov esi,_ecosx
  2742.          mov [ecx+32],esi
  2743.  
  2744.          mov d [ecx+24],0
  2745.  
  2746.          imul edi
  2747.          shrd eax,edx,14
  2748.          neg eax
  2749.          mov [ecx+20],eax
  2750.  
  2751.          mov eax,_ecosz
  2752.          imul edi
  2753.          shrd eax,edx,14
  2754.          mov [ecx+16],eax
  2755.  
  2756.          mov eax,ebx
  2757.          imul edi
  2758.          shrd eax,edx,14
  2759.          mov [ecx+8],eax
  2760.  
  2761.          mov eax,esi
  2762.          imul ebx
  2763.          shrd eax,edx,14
  2764.          neg eax
  2765.          mov [ecx+4],eax
  2766.  
  2767.          ret
  2768.  
  2769. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2770. ; Inverse Rotate by Camera
  2771. ; In:
  2772. ;  EBX = x
  2773. ;  ECX = y
  2774. ;  EBP = z
  2775. ;  ESI => indexer to angles (object number)
  2776. ; Out:
  2777. ;  EBX = x
  2778. ;  ECX = y
  2779. ;  EBP = z
  2780. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2781.  
  2782. icosx    dd 0
  2783. isinx    dd 0
  2784. icosy    dd 0
  2785. isiny    dd 0
  2786. icosz    dd 0
  2787. isinz    dd 0
  2788. ix       dd 0
  2789. iy       dd 0
  2790. iz       dd 0
  2791.  
  2792. _inverse_rotate:
  2793.          push esi ebx ecx ebp
  2794.  
  2795.          mov ax,_vxs[esi*2]
  2796.          neg ax
  2797.          call _cosine
  2798.          mov icosx,eax
  2799.  
  2800.          mov ax,_vxs[esi*2]
  2801.          neg ax
  2802.          call _sine
  2803.          mov isinx,eax
  2804.  
  2805.          mov ax,_vys[esi*2]
  2806.          neg ax
  2807.          call _cosine
  2808.          mov icosy,eax
  2809.  
  2810.          mov ax,_vys[esi*2]
  2811.          neg ax
  2812.          call _sine
  2813.          mov isiny,eax
  2814.  
  2815.          mov ax,_vzs[esi*2]
  2816.          neg ax
  2817.          call _cosine
  2818.          mov icosz,eax
  2819.  
  2820.          mov ax,_vzs[esi*2]
  2821.          neg ax
  2822.          call _sine
  2823.          mov isinz,eax
  2824.  
  2825.          pop ebp ecx ebx
  2826.  
  2827.          mov eax,ebx
  2828.          imul icosz
  2829.          shrd eax,edx,14
  2830.          mov esi,eax
  2831.          mov eax,ecx
  2832.          imul isinz
  2833.          shrd eax,edx,14
  2834.          sub esi,eax
  2835.          mov ix,esi
  2836.  
  2837.          mov eax,ebx
  2838.          imul isinz
  2839.          shrd eax,edx,14
  2840.          mov esi,eax
  2841.          mov eax,ecx
  2842.          imul icosz
  2843.          shrd eax,edx,14
  2844.          add esi,eax
  2845.          mov iy,esi
  2846.  
  2847.          mov ebx,ix
  2848.          mov ecx,iy
  2849.  
  2850.          mov eax,ecx
  2851.          imul icosx
  2852.          shrd eax,edx,14
  2853.          mov esi,eax
  2854.          mov eax,ebp
  2855.          imul isinx
  2856.          shrd eax,edx,14
  2857.          sub esi,eax
  2858.          mov iy,esi
  2859.  
  2860.          mov eax,ecx
  2861.          imul isinx
  2862.          shrd eax,edx,14
  2863.          mov esi,eax
  2864.          mov eax,ebp
  2865.          imul icosx
  2866.          shrd eax,edx,14
  2867.          add esi,eax
  2868.          mov iz,esi
  2869.  
  2870.          mov ecx,iy
  2871.          mov ebp,iz
  2872.  
  2873.          mov eax,ebx
  2874.          imul icosy
  2875.          shrd eax,edx,14
  2876.          mov esi,eax
  2877.          mov eax,ebp
  2878.          imul isiny
  2879.          shrd eax,edx,14
  2880.          sub esi,eax
  2881.          mov ix,esi
  2882.  
  2883.          mov eax,ebx
  2884.          imul isiny
  2885.          shrd eax,edx,14
  2886.          mov esi,eax
  2887.          mov eax,ebp
  2888.          imul icosy
  2889.          shrd eax,edx,14
  2890.          add esi,eax
  2891.          mov iz,esi
  2892.  
  2893.          mov ebx,ix
  2894.          mov ebp,iz
  2895.  
  2896.          pop esi
  2897.          ret
  2898.  
  2899. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2900. ; Rotate point along X axis
  2901. ; In:
  2902. ;  ECX = Y
  2903. ;  EBP = Z
  2904. ;   AX = angle to rotate by
  2905. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2906.  
  2907. _rotate_x:
  2908.          push ebx ecx ebp ax
  2909.          call _cosine
  2910.          mov icosx,eax
  2911.  
  2912.          pop ax
  2913.          call _sine
  2914.          mov isinx,eax
  2915.  
  2916.          pop ebp ecx ebx
  2917.  
  2918.          mov eax,ecx
  2919.          imul icosx
  2920.          shrd eax,edx,14
  2921.          mov esi,eax
  2922.          mov eax,ebp
  2923.          imul isinx
  2924.          shrd eax,edx,14
  2925.          sub esi,eax
  2926.          mov iy,esi
  2927.  
  2928.          mov eax,ecx
  2929.          imul isinx
  2930.          shrd eax,edx,14
  2931.          mov esi,eax
  2932.          mov eax,ebp
  2933.          imul icosx
  2934.          shrd eax,edx,14
  2935.          add esi,eax
  2936.  
  2937.          mov ebp,esi
  2938.          mov ecx,iy
  2939.          ret
  2940.  
  2941. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2942. ; Rotate point along Y axis
  2943. ; In:
  2944. ;  EBX = X
  2945. ;  EBP = Z
  2946. ;   AX = angle to rotate by
  2947. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2948.  
  2949. _rotate_y:
  2950.          push ebx ecx ebp ax
  2951.          call _cosine
  2952.          mov icosy,eax
  2953.  
  2954.          pop ax
  2955.          call _sine
  2956.          mov isiny,eax
  2957.  
  2958.          pop ebp ecx ebx
  2959.  
  2960.          mov eax,ebx
  2961.          imul icosy
  2962.          shrd eax,edx,14
  2963.          mov esi,eax
  2964.          mov eax,ebp
  2965.          imul isiny
  2966.          shrd eax,edx,14
  2967.          sub esi,eax
  2968.          mov ix,esi
  2969.  
  2970.          mov eax,ebx
  2971.          imul isiny
  2972.          shrd eax,edx,14
  2973.          mov esi,eax
  2974.          mov eax,ebp
  2975.          imul icosy
  2976.          shrd eax,edx,14
  2977.          add esi,eax
  2978.  
  2979.          mov ebp,esi
  2980.          mov ebx,ix
  2981.          ret
  2982.  
  2983. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2984. ; Rotate point along Z axis
  2985. ; In:
  2986. ;  EBX = X
  2987. ;  ECX = Y
  2988. ;   AX = angle to rotate by
  2989. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2990.  
  2991. _rotate_z:
  2992.          push ebx ecx ebp ax
  2993.          call _cosine
  2994.          mov icosz,eax
  2995.  
  2996.          pop ax
  2997.          call _sine
  2998.          mov isinz,eax
  2999.  
  3000.          pop ebp ecx ebx
  3001.  
  3002.          mov eax,ebx
  3003.          imul icosz
  3004.          shrd eax,edx,14
  3005.          mov esi,eax
  3006.          mov eax,ecx
  3007.          imul isinz
  3008.          shrd eax,edx,14
  3009.          sub esi,eax
  3010.          mov ix,esi
  3011.  
  3012.          mov eax,ebx
  3013.          imul isinz
  3014.          shrd eax,edx,14
  3015.          mov esi,eax
  3016.          mov eax,ecx
  3017.          imul icosz
  3018.          shrd eax,edx,14
  3019.          add esi,eax
  3020.  
  3021.          mov ecx,esi
  3022.          mov ebx,ix
  3023.          ret
  3024.  
  3025. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  3026. ; _Point_Z: Calculate Z roll direction to line object up with point
  3027. ; In:
  3028. ;  EBX = x point
  3029. ;  ECX = y point
  3030. ;  EBP = z point
  3031. ;   AX = current Y angle of object
  3032. ;   DI = current X angle of object
  3033. ; Out:
  3034. ;   AX = Z angle
  3035. ; Notes:
  3036. ;   u = x*cos(Y) - z*sin(Y)
  3037. ;   v = x*sin(Y) + z*cos(Y)
  3038. ;   y = y*cos(X) - v*sin(X)
  3039. ;   Z = arctan (u/y)         = AX
  3040. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  3041.  
  3042. _point_z:
  3043.          push esi edi ebx ax
  3044.          call _cosine
  3045.          mov icosy,eax
  3046.          pop ax
  3047.          call _sine
  3048.          mov isiny,eax
  3049.  
  3050.          pop ebx
  3051.          imul ebp
  3052.          shrd eax,edx,14
  3053.          mov esi,eax
  3054.          neg esi
  3055.          mov eax,icosy
  3056.          imul ebx
  3057.          shrd eax,edx,14
  3058.          add esi,eax
  3059.          mov ix,esi
  3060.  
  3061.          mov eax,ebx
  3062.          imul isiny
  3063.          shrd eax,edx,14
  3064.          mov esi,eax
  3065.          mov eax,ebp
  3066.          imul icosy
  3067.          shrd eax,edx,14
  3068.          add esi,eax
  3069.  
  3070.          mov ax,di
  3071.          call _cosine
  3072.          mov icosx,eax
  3073.          mov ax,di
  3074.          call _sine
  3075.          mov isinx,eax
  3076.          mov eax,ecx
  3077.          imul icosx
  3078.          shrd eax,edx,14
  3079.          mov edi,eax
  3080.          mov eax,esi
  3081.          imul isinx
  3082.          shrd eax,edx,14
  3083.          sub edi,eax
  3084.  
  3085.          mov eax,edi
  3086.          mov ecx,ix
  3087.          call _arctan
  3088.          pop edi esi
  3089.          ret
  3090.  
  3091.